Как установить видимость кнопки в шаблоне управления стилем xaml на основе наличия дочернего элемента DataGrid

У меня есть объявление стиля в xaml для GroupBox. Это объявление Style включает в себя ControlTemplate, который включает кнопку. Я хотел бы, чтобы видимость кнопки зависела от того, будет ли DataGrid дочерним элементом GroupBox. GroupBox динамически встроен в код программной части.

В коде программной части логическое значение определяет, будет ли DataGrid дочерним элементом GroupBox во время создания GroupBox.

Я думал об использовании логического присоединенного свойства (AP) для GroupBox, которое указывало бы, будет ли DataGrid дочерним элементом GroupBox, но я не уверен, как это будет объявлено в объявлении Style (или если бы я даже объявить там точку доступа) или как я могу использовать точку доступа в коде программной части.

Как установить свойство «Видимость» кнопки на основе наличия DataGrid?

Может кто-нибудь, пожалуйста, дайте мне простой пример того, как я бы настроить это?

Любая помощь приветствуется!


person chuckp    schedule 04.08.2018    source источник


Ответы (1)


Обычно это делается с помощью DataTrigger, хотя вы также можете сделать это с помощью конвертера. В любом случае вам нужно будет выполнить привязку к этому логическому значению в вашем коде. Я предполагаю, что вы установили окно как собственный DataContext, поэтому просто сделайте что-то вроде этого:

<Button Content="Press Me" HorizontalAlignment="Left" VerticalAlignment="Top">
    <Button.Style>
        <Style TargetType="{x:Type Button}">
            <Style.Triggers>
                <DataTrigger Binding="{Binding YourBooleanValue}" Value="False">
                    <Setter Property="Visibility" Value="Hidden" />
                </DataTrigger>
                <DataTrigger Binding="{Binding YourBooleanValue}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Button.Style>
</Button>

ОБНОВИТЬ:

Хорошо, основываясь на дополнительной информации, которую вы предоставили ниже, я думаю, что теперь понимаю, что вы пытаетесь сделать. Пожалуйста, поправьте меня, если что-то из этого не так, но похоже, что вы создаете GroupBox, учитывая, что некоторые из них DataGrid являются дочерними:

        var groupBox1 = new GroupBox();
        this.thePanel.Children.Add(groupBox1);

        var groupBox2 = new GroupBox();
        var dataGrid = new DataGrid();
        dataGrid.Columns.Add(new DataGridTextColumn { Header = "Column1" });
        dataGrid.Columns.Add(new DataGridTextColumn { Header = "Column2" });
        dataGrid.Columns.Add(new DataGridTextColumn { Header = "Column3" });
        groupBox2.Content = dataGrid;
        this.thePanel.Children.Add(groupBox2);

Затем в вашем стиле у вас есть ContentControl для групповых ящиков, содержащий кнопку, и вы хотите, чтобы эта кнопка была видна только в групповых ящиках, у которых есть DataGrid для дочернего элемента? Если это так, то вы можете сделать это достаточно легко с помощью конвертера. Вы привязываете свойство Visibility кнопки к содержимому GroupBox, а затем используете преобразователь для преобразования из него в параметр Visibility:

    <conv:ChildVisibilityConverter x:Key="ChildVisibilityConverter" />

    <Style TargetType="{x:Type GroupBox}">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="GroupBox">
                    <Border BorderBrush="Black" BorderThickness="1" CornerRadius="10" Margin="5" Padding="5" >
                        <StackPanel Orientation="Vertical">
                            <TextBlock Text="Group Box" />
                            <Button Content="Click Me" HorizontalAlignment="Left" VerticalAlignment="Top"
                                    Visibility="{TemplateBinding Content, Converter={StaticResource ChildVisibilityConverter}}" />
                            <ContentPresenter />
                        </StackPanel>
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Фактический преобразователь сам просто просматривает то, что ему было дано (т.е. содержимое GroupBox), проверяет его тип и соответственно возвращает видимость:

public class ChildVisibilityConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null)
            return Visibility.Hidden;
        return (value.GetType() == typeof(DataGrid))
            ? Visibility.Visible
            : Visibility.Hidden;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

Итак, для этого блока кода, который я разместил выше, вы увидите кнопку только во втором GroupBox:

введите здесь описание изображения

Это отвечает на вопрос?

person Mark Feldman    schedule 04.08.2018
comment
Спасибо Марк!! ... Мне нужно создать МНОГИЕ из этих групповых окон в коде программной части, и у некоторых может быть дочерний элемент DataGrid, а у других - нет. Вот почему я подумал, что прикрепленное свойство для GroupBox будет полезно (но я не уверен, что это способ решить эту проблему). Является ли YourBooleanValue прикрепленным свойством? - person chuckp; 05.08.2018
comment
Нет, это просто обычное свойство, хотя оно должно поддерживать уведомление об изменении свойств, если вы хотите, чтобы видимость кнопок автоматически менялась при обновлении. Честно говоря, вы немного усложняете себе задачу, делая такие вещи по-старому, MVVM был специально разработан, чтобы сделать такие задачи намного проще. - person Mark Feldman; 05.08.2018
comment
Марк ... поверьте мне, когда я говорю вам, что я новичок в этой кодовой базе, и в ее нынешнем состоянии она оставляет желать лучшего. Планируется полное переписывание базы кода, при этом MVVM будет большой частью переделки :-) Чтобы было ясно, видимость кнопок должна быть установлена ​​на основе GroupBox by GroupBox. Вот почему я подумал об использовании прикрепленного свойства для GroupBox, но я просто не знаю, как его настроить. Спасибо еще раз!! - person chuckp; 05.08.2018
comment
@chuckp Ответ обновлен, дайте мне знать, если я что-то неправильно понял. - person Mark Feldman; 05.08.2018
comment
МОЙ БОГ!! ... Я пытался придумать свойство GroupBox для привязки к видимости кнопки, и мне даже не пришло в голову просто посмотреть на значение свойства Content, которое установлено в коде программной части. Ваше решение работает ОТЛИЧНО!! Виртуальный напиток для взрослых по вашему выбору, Марк!! Огромное спасибо!! - person chuckp; 05.08.2018