【发布时间】:2015-05-28 08:25:20
【问题描述】:
我正在尝试创建一个撤消/重做系统。当前,当用户执行某项操作时,原始对象和新对象将按“操作”复制到列表中。如果我按下撤消按钮,我想再次将原始值分配给新值。
我已经能够在列表中同时获取新对象和原始对象,但是使用我所做的撤消再次分配旧对象时出现错误。它在包含所有可以更改但不在视图中更新的主列表中更新。
undo方法是这样的:
for (int t = 0; t < mainData.GroupModelList.Count; ++t)
{
if (mainData.GroupModelList[t].Name == commandList.ElementAt(position).groupModelNew.Name)
{
mainData.GroupModelList[t] = new ViewModels.GroupViewModel(commandList.ElementAt(position).groupModelOrig);
break;
}
}
这会调用 GroupViewModel 的构造函数:
public GroupViewModel(GroupViewModel selectedGroup)
{
groupModel = new GroupModel();
// values are assigned from the selectedGroup here (which is the original object in the UndoRedo part)
// ...
OnPropertyChanged(null);
}
这是 OnPropertyChanged 方法:
private void OnPropertyChanged(string Property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(Property));
}
}
我在某处读到,在 PropertyChangedEventArgs 使用“null”会使所有内容都更新,所以这就是我尝试过的,但它不起作用。
在更多断点之后,我注意到PropertyChanged 在调用新构造函数时为空,这可能是问题所在。不过,它确实可以在没有撤消/重做的情况下工作。 (当简单地改变对象使用文本框或类似的值时)
我还读到我应该将 DataContext 指向对象本身,但这似乎是不可能的,因为该对象没有 DataContext 属性。
编辑:人们告诉我应该使用 ObservableCollection。我已经在使用它了。像这样:(这是 View 可以访问的列表)
private ObservableCollection<GroupViewModel> groupModelList = new ObservableCollection<GroupViewModel>();
public ObservableCollection<GroupViewModel> GroupModelList
{
get { return groupModelList; }
}
编辑:这是绑定到视图的方式:
首先是 XAML 中的绑定
<Window.Resources>
<vm:MainViewModel x:Key="MainViewModel" />
</Window.Resources>
MainViewModel 拥有一个 MainData 类型的对象,并且在该类内部有一个 ObservableCollection<GroupViewModel>。
例如,这是将列表中选定项目的名称绑定到视图中的文本框的代码:(第一行是显示 GroupViewModel 列表中所有项目的列表框,第二行是我想给出的文本框一个例子)
<ListBox DisplayMemberPath="Name" Height="412" HorizontalAlignment="Left" ItemsSource="{Binding Source={StaticResource MainViewModel}, Path=mainData.FilteredGroupModelList, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Margin="10,44,0,0" Name="lbFoundItems" SelectedItem="{Binding Source={StaticResource MainViewModel}, Path=SelectedGroup, Mode=OneWayToSource}" VerticalAlignment="Top" Width="250" SelectionMode="Single" />
<ComboBox Height="23" HorizontalAlignment="Left" ItemsSource="{Binding ElementName=lbFoundItems, Path=SelectedItem.Types, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Margin="436,378,0,0" Name="cmbTypes" SelectedItem="{Binding Source={StaticResource MainViewModel}, Path=SelectedType, Mode=OneWayToSource}" VerticalAlignment="Top" Width="180" />
这也是SelectedGroup 变量,它包含对列表框中所选项目的引用:
private GroupViewModel selectedGroup;
public GroupViewModel SelectedGroup
{
get { return selectedGroup; }
set
{
selectedGroup = value;
OnPropertyChanged("SelectedGroup");
}
}
【问题讨论】:
-
在哪里分配 GroupViewModel 的新实例?持有该实例的对象/视图模型需要调用 PropertyChangedEvent
-
在第一段代码中,您可以看到我再次将旧对象分配给新对象。我搜索对象的主列表,然后将其分配给
new。像这样:mainData.GroupModelList[t] = new ViewModels.GroupViewModel(commandList.ElementAt(position).groupModelOrig);。此外,正如您在第二段代码中看到的那样,在 viewModel 的构造函数中调用 PropertyChanged