Как настроить видимость Button в xaml Style ControlTemplate на основе наличия дочернего элемента DataGrid

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

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

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

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

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

Любая помощь очень ценится!

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 for GroupBoxes, содержащий кнопку, и вы хотите, чтобы эта кнопка была видна только в групповых полях, которые имеют 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:

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

Другие вопросы по тегам