【问题标题】:Trigger for auto-generated DataGrid column触发自动生成的 DataGrid 列
【发布时间】:2019-02-14 08:58:44
【问题描述】:

我目前从事一个 WPF 项目,该项目在自动生成的数据网格中处理数据。如何设置触发器,根据空文本框更改列的背景颜色?

我当前的用户控件 XAML 创建了一个网格,其中保留了数据网格。我为每个 DataGridColumnHeader 设置了一个新的 ContentTemplate,其中保留了一个 TextBlock(用于实际标题)和一个用于过滤的 TextBox。

我尝试为 DataGridCell 设置触发器,该触发器有效,但仅更改了单元格的颜色。我找不到数据网格列的特定目标类型。

<UserControl x:Class="...">
<Grid>
    <DataGrid AutoGenerateColums="True" IsReadOnly="True" x:Name="MyDataGrid">
        <DataGrid.Resources>
            <Style TargetType="x:Type DataGridColumnHeader=">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock x:Name="myBlock" Text="{Binding}" TextWrapping="Wrap" />
                                <TextBox x:Name="myBox" KeyUp="KeyUpEvent" />
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
    </DataGrid>
</Grid>

如果 TextBox 填充有内容,我希望更改数据网格列的颜色。目前我不知道如何为数据网格列设置特定触发器,如果​​该列是自动生成的。 编辑 #1: 类似的东西:

这是数据网格未设置任何过滤器的情况。但是,只要您在其中一个过滤器中输入过滤器文本,外观就会发生变化,如下所示:

编辑 #2:

我能够构建一个以编程方式为行着色的解决方案,而无需为标题着色。那不见了。你有什么建议吗?

见以下代码:

private void StyleRows(string text, string name)
{
    if(text != "" && column != "")
    {
        foreach(DataGridColumn column in DataGrid.Columns)
        {
            if(column.Header == column)
            {
                Style style = new Style(typeof(DataGridCell));
                style.Settes.Add(new Setter(DataGridCell.BackgroundProperty, System.Windows.Media.Brushes.Red));
                column.cellStyle = style
            }
        }
    }
}

问题: 有没有办法在 XAML 中做到这一点?

感谢您的帮助!

【问题讨论】:

    标签: c# wpf triggers datagrid


    【解决方案1】:

    无法仅在 XAML 中实现

    你可以尝试调整一个ViewModel为每一列提供TextBox的内容是否为空(将TextBox.Text绑定到属性并提供bool属性检查字符串为空或空)。但它也不是“仅限 XAML” 解决方案。

    如果您设置了CellStyle,您将需要从模板观察控件并使用触发器,但您无权访问它。

    我会使用Behavior。编写 Behavior 后,您可以轻松仅在 XAML 中使用/重用它,而无需触摸/调整后面的代码。

    public class ObserveEmpty : Behavior<TextBox>
    {
        public Control TargetControl
        {
            get { return (Control)GetValue(TargetControlProperty); }
            set { SetValue(TargetControlProperty, value); }
        }
        public static readonly DependencyProperty TargetControlProperty =
            DependencyProperty.Register(nameof(TargetControl), typeof(object), typeof(ObserveEmpty), new PropertyMetadata(null, TargetCtlChanged));
    
        private static void TargetCtlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            (d as ObserveEmpty)?.SetTargetBackground();
        }
        public Brush TargetBgrndBrushOnEmpty { get; set; }
        public Brush TargetBgrndBrush { get; set; }
    
    
        protected override void OnAttached()
        {
            base.OnAttached();
            SetTargetBackground();
            AssociatedObject.TextChanged += AssociatedObject_TextChanged;
        }
        protected override void OnDetaching()
        {
            base.OnDetaching();
            AssociatedObject.TextChanged -= AssociatedObject_TextChanged;
        }
        private void AssociatedObject_TextChanged(object sender, TextChangedEventArgs e)
        {
            SetTargetBackground();
        }
        private void SetTargetBackground()
        {
            if (TargetControl != null)
            {
                var brush = string.IsNullOrEmpty(AssociatedObject?.Text) ? TargetBgrndBrushOnEmpty : TargetBgrndBrush;
    
                TargetControl.Background = brush;
    
                var dgrClmnHdr = TargetControl as DataGridColumnHeader;
                if (dgrClmnHdr?.Column != null)
                {
                    Style style = new Style(typeof(DataGridCell));
                    style.Setters.Add(new Setter(DataGridCell.BackgroundProperty, brush));
                    dgrClmnHdr.Column.CellStyle = style;
                }
            }
        }
    }
    
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        <DataGrid.Resources>
            <Style TargetType="{x:Type DataGridColumnHeader}">
                <Setter Property="ContentTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <StackPanel>
                                <TextBlock x:Name="myBlock" Text="{Binding}" TextWrapping="Wrap" />
                                <TextBox x:Name="myBox">
                                    <i:Interaction.Behaviors>
                                        <local:ObserveEmpty TargetBgrndBrush="Aqua" TargetBgrndBrushOnEmpty="Red" 
                                                            TargetControl="{Binding RelativeSource={RelativeSource AncestorType=DataGridColumnHeader}, Mode=OneWay}"/>
                                    </i:Interaction.Behaviors>
                                </TextBox>
                            </StackPanel>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </DataGrid.Resources>
    

    【讨论】:

    • 我做了一些更改和编辑。仅更改 DataGridColumnHeader 的背景颜色并不是全部(看图片)。我能够以编程方式设置行的背景颜色,但实际上我想通过 XAML 文件来做到这一点。而且,除此之外,我还想更改 DataGridColumnHeader 背景。
    猜你喜欢
    • 2014-03-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-26
    • 2014-06-06
    • 2012-02-19
    • 1970-01-01
    相关资源
    最近更新 更多