繁体   English   中英

WPF MVVM-Datagrid不会更新子项的更改属性

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

我在MVVM应用程序内的WPF表单上有一个可编辑的数据网格。

用户可以在此页面上执行两种可能的操作,这些操作导致其中一行中的某些数据发生更改。 其中一个可编辑字段-请求-可能导致另一个属性发生更改,并且样式触发器取决于其值:

public bool OverRequested
{
    get
    {
        if(this.Requested > this.Volume)
        {
            return true;
        }
        return false;
    }
}

在XAML中:

<DataGridTextColumn Header="Requested" Binding="{Binding Requested}">
    <DataGridTextColumn.CellStyle>
        <Style TargetType="DataGridCell">
            <Style.Triggers>
                <DataTrigger Binding="{Binding OverRequested}" Value="true">
                    <Setter Property="Foreground" Value="Red"/>
                    <Setter Property="ToolTip" Value="The requested volume is greater than the available volume" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </DataGridTextColumn.CellStyle>
</DataGridTextColumn>

另一个是按钮,用于更新该行后面的数据项并更改该项的值。

尽管数据网格本身可以响应更改-如果您在基础ObservableCollection中添加或删除行,则它会在UI中相应地进行更新-对这些行下方项目的这些属性的更改不会更新。

我了解这是设计使然,在某种意义上说,对observableCollection中的项目所做的更改不会冒泡,必须特别注意,但是我正在努力寻找如何实现我想要的目标。

我已经尝试-像其他地方建议的那样-覆盖ObservableCollection上CollectionChanged的事件处理程序,以向其中的项目添加通知警报:

private void ObservableCollection_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    if (e.NewItems != null)
    {
        foreach (var item in e.NewItems)
        {
            (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
        }
    }
}

但是里面的项目没有实现INotifyPropertyChanged接口-它们是Entity Framework对象,而不是ViewModels。 因此强制转换失败。

有办法实现吗? 仅需要监视两个属性,我很乐意手动进行操作-但即使调用OnPropertyChanged(“”)来更新ViewModel中的所有属性也不会导致数据网格中的那些属性刷新。

也许您可以使用转换器尝试另一种方法。 我有一个执行类似操作的应用程序。 我通常需要一个测试应用程序来使这些东西正确无误,但是请尝试以下操作:

<DataGridTextColumn Header="Requested" Binding="{Binding Requested}">
<DataGridTextColumn.CellStyle>
    <Style TargetType="DataGridCell">
         <Setter Property="Foreground">
              <Setter.Value>
                <MultiBinding Converter="{StaticResource OverRequestedForegroundMultiConverter}">
                    <Binding Path="Requested" />
                    <Binding Path="Volume" />
                </MultiBinding>
              </Setter.Value>
         </Setter>
         <Setter Property="ToolTip">
              <Setter.Value>
                <MultiBinding Converter="{StaticResource OverRequestedTooltipMultiConverter}">
                    <Binding Path="Requested" />
                    <Binding Path="Volume" />
                </MultiBinding>
              </Setter.Value>
         </Setter>
    </Style>
</DataGridTextColumn.CellStyle>

转换器看起来像这样:

public class OverRequestedForegroundMultiConverter : IMultiValueConverter
{
    #region IValueConverter Members

    public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value.Length == 2)
        {
            if (value[0] is int && value[1] is int)
            {
                int requested = (int)value[0];
                int volume = (int)value[1];
                if (requested > volume)
                    return Colors.Red;
            }
        }
        return Colors.Gray; // Or whatever color you want
    }

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

    #endregion
}

    public class OverRequestedTooltipMultiConverter : IMultiValueConverter
    {
        #region IValueConverter Members

        public object Convert(object[] value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value != null && value.Length == 2)
            {
                if (value[0] is int && value[1] is int)
                {
                    int requested = (int)value[0];
                    int volume = (int)value[1];
                    if (requested > volume)
                        return "The requested volume is greater than the available volume";
                }
            }
            return null;
        }

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

        #endregion
    }

不要忘记将转换器添加到您的app.xaml:

<app:OverRequestedForegroundMultiConverter x:Key="OverRequestedForegroundMultiConverter" />
<app:OverRequestedTooltipMultiConverter x:Key="OverRequestedTooltipMultiConverter" />

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM