如何根据 DataGrid 子项的存在设置 xaml Style ControlTemplate 中 Button 的可见性

How to set visibility of Button in xaml Style ControlTemplate based on presence of DataGrid child

我在 xaml 中有一个 GroupBox 的样式声明。此 Style 声明包括一个包含 Button 的 ControlTemplate。我希望 Button 可见性取决于 DataGrid 是否是 GroupBox 的子项。 GroupBox 是在代码隐藏中动态构建的。

在代码隐藏中,布尔值确定在创建 GroupBox 时 DataGrid 是否是 GroupBox 的子项。

我考虑过为 GroupBox 使用一个布尔值 Attached 属性 (AP),它将指定 DataGrid 是否是 GroupBox 的子项,但我不确定这将如何声明样式声明(或者如果我什至在那里声明一个 AP),或者我如何在代码隐藏中使用 AP。

如何根据 DataGrid 的存在设置按钮的可见性 属性?

有人可以给我一个简单的例子来说明我将如何设置吗?

非常感谢任何帮助!

执行此操作的常用方法是使用 DataTrigger,但您也可以使用转换器来执行此操作。无论哪种方式,您都需要在后面的代码中绑定到该布尔值。我假设您已将 window 设置为它自己的 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);

那么在您的样式中,您有一个包含按钮的 GroupBox 的 ContentControl,并且您只希望该按钮在具有子 DataGrid 的组框上可见?如果是这种情况,那么您可以使用转换器轻松完成。您将按钮的可见性 属性 绑定到 GroupBox 的内容,然后使用转换器将其转换为可见性设置:

    <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 的内容),检查其类型并相应地 returns 可见性:

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 中看到按钮:

这是否回答了问题?