簡體   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