wpf databound RadGrid - 为什么网格未检测到视图模型的更改?
我正在尝试生成一个与 Visual Studio 中的错误列表非常相似的错误列表。
我有一个视图和视图模型。我更新单例视图模型并通知属性发生更改,这是实际消息(错误和警告)。然而,网格保持不变——出了什么问题?!
我已经逐步完成,集合 _messages 已正确更新,并且初始消息已正确显示,但在视图模型更新后仍保留在视图中。换句话说,这应该是根据正确的视图模型进行视图更新的问题。
我知道 RadPane 中的错误会导致窗格失去与视图模型的连接,并已实施标准解决方法。
视图模型实现 INotifyPropertyChanged。
(在 xaml 中添加了 NotifySourceUpdated 试图补救,但无济于事)
(由于 Stackoverflow 限制,视图中的括号被替换)
感谢您的任何输入和见解...
Anders,丹麦
视图:
[Controls:RadPane x:Class="Rap1D.Rap1D_WPF.Views.ErrorListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:Controls="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Docking" xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView" mc:Ignorable="d"
d:DesignHeight="74" d:DesignWidth="298" Header="{Binding Header}" DataContextChanged="RadPane_DataContextChanged"]
[Grid]
[telerik:RadGridView AutoGenerateColumns="False" x:Name="grid" ItemsSource="{Binding Path=Messages, NotifyOnSourceUpdated=True}" Margin="0,0,0,37"]
[telerik:RadGridView.Columns]
[telerik:GridViewDataColumn Header="Message" DataMemberBinding="{Binding Path=Message, NotifyOnSourceUpdated=True}" /]
[/telerik:RadGridView.Columns]
[/telerik:RadGridView]
[/Grid]
[/Controls:RadPane]
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using Rap1D.ViewModelLayer.Interfaces;
using Rap1D.ViewModelLayer.Interfaces.TreeViewItems;
namespace Rap1D.ViewModelLayer.Implementations
{
public class ErrorListViewModel :ViewModelBase, IErrorListViewModel
{
private readonly List<INotificationMessage> _messages;
public ErrorListViewModel()
{
_messages = new List<INotificationMessage>();
}
public string Header
{
get { return "Error List"; }
}
public IEnumerable<INotificationMessage> Messages
{
get { return _messages; }
}
public void RemoveNotificationsForItem(IProductComponentViewModel productComponentViewModel)
{
var toDelete = (from m in _messages
where m.Item == productComponentViewModel
select m).ToList();
foreach (var notificationMessage in toDelete)
{
_messages.Remove(notificationMessage);
}
OnPropertyChanged("Messages");
}
public void AddNotifications(IProductComponentViewModel productComponentViewModel, IEnumerable<INotificationMessage> list)
{
_messages.AddRange(list);
OnPropertyChanged("Messages");
}
}
}
ErrorManager:
using System.Collections.Generic;
using Rap1D.ViewModelLayer.Interfaces;
using Rap1D.ViewModelLayer.Interfaces.Managers;
using Rap1D.ViewModelLayer.Interfaces.Providers;
using Rap1D.ViewModelLayer.Interfaces.TreeViewItems;
namespace Rap1D.ViewModelLayer.Implementations.Managers
{
public class ErrorManager : IErrorManager
{
private readonly IErrorListViewModelProvider _errorListViewModelProvider;
public ErrorManager(IErrorListViewModelProvider errorListViewModelProvider)
{
_errorListViewModelProvider = errorListViewModelProvider;
}
public void UpdateNotificationsForItem(IProductComponentViewModel productComponentViewModel,
IEnumerable<INotificationMessage> list)
{
var errorListViewModel = _errorListViewModelProvider.GetViewModel();
errorListViewModel.RemoveNotificationsForItem(productComponentViewModel);
errorListViewModel.AddNotifications(productComponentViewModel, list);
}
}
}
I'm trying to produce an error list much like the one in Visual Studio.
I have a view and the view model. I update the singleton view model and notify that changes have occurred to the property which are the actual messages (errors and warnings). However, the grid remains unchanged - what is wrong?!
I have stepped through, the collection _messages is updated correctly and an initial message is shown correctly but remain in view after the view model update. In other words it should be a matter of making the view update according to a correct view model.
I am aware of the bug in RadPane that causes Panes to loose it's connection to view model and have implemented the standard workaround.
The view model implements INotifyPropertyChanged.
(The NotifySourceUpdated in xaml added in an attempt to remedy, but to no avail)
(Brackets replaced in View due to Stackoverflow restrictions)
Thanks for any input and insight...
Anders, Denmark
View:
[Controls:RadPane x:Class="Rap1D.Rap1D_WPF.Views.ErrorListView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:Controls="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.Docking" xmlns:telerik="clr-namespace:Telerik.Windows.Controls;assembly=Telerik.Windows.Controls.GridView" mc:Ignorable="d"
d:DesignHeight="74" d:DesignWidth="298" Header="{Binding Header}" DataContextChanged="RadPane_DataContextChanged"]
[Grid]
[telerik:RadGridView AutoGenerateColumns="False" x:Name="grid" ItemsSource="{Binding Path=Messages, NotifyOnSourceUpdated=True}" Margin="0,0,0,37"]
[telerik:RadGridView.Columns]
[telerik:GridViewDataColumn Header="Message" DataMemberBinding="{Binding Path=Message, NotifyOnSourceUpdated=True}" /]
[/telerik:RadGridView.Columns]
[/telerik:RadGridView]
[/Grid]
[/Controls:RadPane]
ViewModel:
using System;
using System.Collections.Generic;
using System.Linq;
using Rap1D.ViewModelLayer.Interfaces;
using Rap1D.ViewModelLayer.Interfaces.TreeViewItems;
namespace Rap1D.ViewModelLayer.Implementations
{
public class ErrorListViewModel :ViewModelBase, IErrorListViewModel
{
private readonly List<INotificationMessage> _messages;
public ErrorListViewModel()
{
_messages = new List<INotificationMessage>();
}
public string Header
{
get { return "Error List"; }
}
public IEnumerable<INotificationMessage> Messages
{
get { return _messages; }
}
public void RemoveNotificationsForItem(IProductComponentViewModel productComponentViewModel)
{
var toDelete = (from m in _messages
where m.Item == productComponentViewModel
select m).ToList();
foreach (var notificationMessage in toDelete)
{
_messages.Remove(notificationMessage);
}
OnPropertyChanged("Messages");
}
public void AddNotifications(IProductComponentViewModel productComponentViewModel, IEnumerable<INotificationMessage> list)
{
_messages.AddRange(list);
OnPropertyChanged("Messages");
}
}
}
ErrorManager:
using System.Collections.Generic;
using Rap1D.ViewModelLayer.Interfaces;
using Rap1D.ViewModelLayer.Interfaces.Managers;
using Rap1D.ViewModelLayer.Interfaces.Providers;
using Rap1D.ViewModelLayer.Interfaces.TreeViewItems;
namespace Rap1D.ViewModelLayer.Implementations.Managers
{
public class ErrorManager : IErrorManager
{
private readonly IErrorListViewModelProvider _errorListViewModelProvider;
public ErrorManager(IErrorListViewModelProvider errorListViewModelProvider)
{
_errorListViewModelProvider = errorListViewModelProvider;
}
public void UpdateNotificationsForItem(IProductComponentViewModel productComponentViewModel,
IEnumerable<INotificationMessage> list)
{
var errorListViewModel = _errorListViewModelProvider.GetViewModel();
errorListViewModel.RemoveNotificationsForItem(productComponentViewModel);
errorListViewModel.AddNotifications(productComponentViewModel, list);
}
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
所要做的就是将 List 更改为 ObservableCollection。
有人可以解释为什么我最初的解决方案没有按预期工作吗?
All it took was changing to List to ObservableCollection.
Can someone explain why my initial solution didn't work as expected?
ObservableCollections 支持 PropertyChangeNotification;其他集合需要
RaisePropertyChanged("ObjectName")
。ObservableCollections support PropertyChangeNotification; other collections require
RaisePropertyChanged("ObjectName")
.