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

时间:2014-04-04 10:36:50

标签: c# wpf xaml mvvm datagrid

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

这个SO答案(关于这个问题的另一个问题)表明问题的一个方法是使用转换器:

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

对于我的一个场景,项目的样式取决于它的值,并且可以通过用户编辑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();
    }
}

顺便说一句,我很惊讶进入转换器的价值变成了预订 - 这就是绑定的内容,而不是*列 - 我期望获得字符串值状态。可能有用的是知道为什么会这样,因为它可能与答案有关。

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

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

SelectedBooking是一个保存当前所选行的属性。而我正在绝望地解雇一个空的OnPropertyChanged,试图让它更新。

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

1 个答案:

答案 0 :(得分:1)

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

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

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