![](/img/trans.png)
[英]WPF MVVM - Update Datagrid of the MainView from a child viewmodel
[英]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.