【问题标题】:WPF - Value inside datagrid fails to update converter when changed externallyWPF - 数据网格内的值在外部更改时无法更新转换器
【发布时间】:2014-04-04 10:36:49
【问题描述】:

事实证明,从 ObservableCollection 中的项目中冒泡属性更改非常困难 - 默认情况下,它仅在修改集合本身时引发更改事件,而不是其中的项目。

这个 SO 答案(对我关于该主题的另一个问题)表明解决问题的一种方法是使用转换器:

WPF MVVM - Datagrid does not update changed properties of child items

对于我的一个场景,项目的样式取决于它的值,并且可以通过用户编辑 DataGrid 来更改该值,它工作得很好。

但是,在同一个 DataGrid 中,可以通过按下按钮来更新另一个字段 - 该按钮位于同一个 ViewModel 中,但它不属于 datagrid 本身。我尝试了一个类似的技巧来让它工作:

<DataGridTextColumn Header="Status" Binding="{Binding Status}" IsReadOnly="True">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Setter Property="Background">
                <Setter.Value>
                    <Binding Converter="{StaticResource BookingBackgroundConverter}" />
                </Setter.Value>
            </Setter>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

还有转换器:

public class BookingBackgroundConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        Booking b = (Booking)value;

        switch(b.Status)
        {
            case "Booking" :
                return Brushes.LightBlue;
            case "Booked" :
                return Brushes.LightGreen;
            default :
                return Brushes.Transparent;
        }
    }

    public object ConvertBack(object value, Type TargetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

顺便说一句,我很惊讶进入 Converter 的值竟然是一个 Booking - 这是 row 绑定的,而不是 *column - 我期望得到的字符串值地位。知道为什么会这样可能会很有用,因为它可能与答案有关。

无论如何,这是改变状态的按钮单击命令:

private void BookCount()
{
    SelectedBooking.Status = "Booking";
    rep.SaveChanges();
    OnPropertyChanged("");
}

SelectedBooking 是一个包含当前选定行的属性。我绝望地发射了一个空的 OnPropertyChanged 来尝试更新它。

但没有乐趣 - 转换器代码在视图重新加载之前不会受到影响。为什么转换器方法适用于数据网格编辑而不是按钮点击,我可以做些什么来让按钮点击以直观地更新状态列?

【问题讨论】:

    标签: c# wpf xaml mvvm datagrid


    【解决方案1】:

    您更改了Status,但绑定了整个Booking 对象,这意味着它只会在整个对象更改时触发,而不是在该对象中的任何属性更改时触发。改为绑定Status

    <Binding Path=Status, Converter="{StaticResource BookingBackgroundConverter}" />
    

    并更改转换器以使用您的预订状态而不是 Booking 对象。如果您需要传递多个值,请使用 IMultiValueConverterMultiBinding

    【讨论】:

    • 这实际上不起作用,但是 +1 告诉我您需要在单值转换器中指定路径 - 我认为它会自动推断出这一点。
    • 什么不起作用? Status 值更改时仍不调用转换器? Booking 类是否实现了INotifyPropertyChanged
    • 不,Booking 没有实现 INotifyPropertyChanged。这是一个实体框架类。在其他地方,这不是问题,因为我一直在将 INotfiyPropertyChanged 添加到 ViewModel 并通过它公开对象。我不清楚为什么 Booking 在编辑网格时会更新,但在按钮单击时不会更新
    • Edit 意味着值更改,因此它会刷新您的数据,而按钮单击不会。如果它是 EF 对象,那么最好的解决方案是像在其他地方一样创建视图模型包装器。
    猜你喜欢
    • 1970-01-01
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 2019-03-03
    • 1970-01-01
    • 2018-05-31
    • 1970-01-01
    相关资源
    最近更新 更多