WPF - 在外部更改时,数据网格中的值无法更新转换器

本文关键字:网格 转换器 更新 数据网 数据 外部 WPF | 更新日期: 2023-09-27 17:56:41

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

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

WPF MVVM - 数据网格不更新子项的已更改属性

对于我的一个场景,其中项的样式取决于其值,并且可以通过用户编辑 DataGrid 来更改该值,它运行良好。

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

<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();
    }
}

顺便说一句,我很惊讶进入转换器的值竟然是预订 - 这是该行绑定的内容,而不是 * 列 - 我期望获得 Status 的字符串值。了解为什么会这样可能会有所帮助,因为它可能对答案有影响。

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

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

选定预订是保存当前所选行的属性。我正在绝望地发射一个空的 OnPropertyChanged 试图让它更新。

但是没有乐趣 - 转换器代码在视图重新加载之前不会被击中。为什么转换器方法适用于 datagrid 编辑,但不适用于按钮单击,我该怎么做才能让按钮单击直观地更新状态列?

WPF - 在外部更改时,数据网格中的值无法更新转换器

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

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

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