【问题标题】:WPF DataGrid DataTrigger Binding on DataContext propertyDataContext 属性上的 WPF DataGrid DataTrigger 绑定
【发布时间】:2016-10-28 16:35:59
【问题描述】:

DataContext 属性的正确 DataTrigger 绑定是什么? 我有一个像这样绑定的 DataGrid:

XAML:

<DataGrid x:Name="dataGrid" Grid.Row="4" Grid.ColumnSpan="2"
    ItemsSource="{Binding}"
    CellStyle="{StaticResource RowStateStyle}"
>
</DataGrid>

在 .cs 中,网格绑定到 DataTable,因此单元格的 DataContext 是 DataRowView,包含 Row 作为属性:

// DataTable containing lots of rows/columns
dataGrid.DataContext = dataTable; 

编辑:

参考 ASh 的解决方案,我编辑了样式并将 Triggers for Unchanged 和 Modified 放入:

    <Style x:Key="RowStateStyle" TargetType="{x:Type DataGridCell}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=DataContext.Row.RowState,
                RelativeSource={RelativeSource Self}}" Value="Unchanged">
                <Setter Property="Foreground" Value="Green" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=DataContext.Row.RowState,
                RelativeSource={RelativeSource Self}}" Value="Modified">
                <Setter Property="Foreground" Value="Yellow" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=Content.Text,
                RelativeSource={RelativeSource Self}}" Value="test">
                <Setter Property="Foreground" Value="Red" />
            </DataTrigger>
        </Style.Triggers>
    </Style>

在 Content.Text 上触发非常好,Unchanged 也是如此。但是,当我修改一个单元格(因此 DataRowState = Modified)时,什么也没有发生并且颜色保持绿色。有什么解决办法吗?

【问题讨论】:

    标签: c# wpf xaml datagrid datatrigger


    【解决方案1】:

    DataTrigger 对我有用,如果我

    1. 使用DataContext.Row.RowState路径

    2. 不要使用Mode=TwoWay

    3. 设置值时删除枚举名称DataRowState

    <DataTrigger Binding="{Binding Path=DataContext.Row.RowState,
                 RelativeSource={RelativeSource Self}}" 
                 Value="Unchanged">
        <Setter Property="Foreground" Value="Red" />
    </DataTrigger>
    

    我找到了另一个与此问题相关的帖子

    WpfToolkit DataGrid: Highlight modified rows

    没有通知RowState 更改的默认机制。但是可以在派生的 dataTable 类中创建一个:

    public class DataTableExt: DataTable
    {
        protected override DataRow NewRowFromBuilder(DataRowBuilder builder)
        {
            return new DataRowExt(builder);
        }
    
        protected override void OnRowChanged(DataRowChangeEventArgs e)
        {
            base.OnRowChanged(e);
            // row has changed, notifying about changes
            var r = e.Row as DataRowExt;
            if (r!= null)
                r.OnRowStateChanged();
        }
    }
    

    使用派生的 dataRow 类:

    public class DataRowExt: DataRow, INotifyPropertyChanged
    {
        protected internal DataRowExt(DataRowBuilder builder) : base(builder)
        {
        }
    
        internal void OnRowStateChanged()
        {
            OnPropertyChanged("RowState");
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    【讨论】:

    • 不幸的是我还没到那里。查看我编辑的帖子。
    • @ray,我猜DataRowRowState 更改时不会引发事件或通知。现在无法检查或建议任何修复
    • 当我“重绘”网格(例如重新排序)时,变化是可视化的。所以要么是一个小技巧:每当单元格发生变化时重新绘制行,或者解决方案from here。然而,这将非常烦人,而不是简单地触发像 DataGrid_CellEditEnding 这样的事件并且只是按代码更改颜色(只需 3 行代码)。你说什么?
    • @ray,看看我的编辑有一些想法。我一直忘记在 xaml (sigh) 中使用枚举的冗长但类型安全的方法。
    • 抱歉我迟到的回复。我已经实现了这种方法 - 无论出于何种原因,只有在重新绘制网格(排序 cols)后才能显示更改。我已经调试并且所有方法(OnRowStateChanged、OnPropertyChanged)都按预期调用。因此,我真的不明白为什么它仍然不起作用。另一个论坛建议完全撤消这种方法并创建类而不是使用 DataTable - 也是为了追求 WPF 的 MVVM。你怎么看?
    猜你喜欢
    • 2013-06-18
    • 2019-04-29
    • 2012-12-25
    • 2013-11-16
    • 1970-01-01
    • 2010-11-01
    • 1970-01-01
    • 2014-08-15
    • 2013-10-19
    相关资源
    最近更新 更多