更改视图模型中可观察集合的属性而不选择它
本文关键字:属性 选择 集合 观察 视图 模型 | 更新日期: 2023-09-27 18:36:28
在我的程序中,我有一个通过使用ObservableCollection
通过 ViewModel 实现的TreeView
。每个集合都有一个名为 Rank
的属性。这应该用作集合项的索引。
在这个问题中,我能够让我的TreeView
节点使用ObservableCollection.Move();
切换位置
但是,在切换节点的位置后,我需要更正/更改节点等级的值,以便我可以继续操作它们。
这应该有助于解释我在做什么:
视图 -- 代码隐藏:
//Button Click Event -- This makes the Selected Node switch places with the node above it
private void shiftUp_Click(object sender, RoutedEventArgs e)
{
//if a node is selected
if (UCViewModel.TreeViewViewModel.SelectedItem != null)
{
//If the selected Node is not in the 0 position (can not move up anymore)
if (UCViewModel.TreeViewViewModel.Collection<TreeViewModel>.IndexOf(UCViewModel.TreeViewViewModel.SelectedItem) != 0)
{
int oldIndex = UCViewModel.TreeViewViewModel.SelectedItem.Rank;
int newIndex = oldIndex--;
UCViewModel.TreeViewViewModel.Collection<TreeViewModel>.Move(oldIndex, newIndex);
//**Pseudo code trying to explain what I want to do
//**get item at specific index and change the Rank value
//Collection item at index (newIndex).Rank -= 1;
//Collection item at index (oldIndex).Rank += 1;
}
}
}
用户控件 -- XAML:
<TreeView ItemsSource="{Binding TreeViewViewModel.Collection<TreeModel>}" ... />
移动后如何更正Rank
值?
编辑
如上所述,我在TreeView
的数据模型中有一个Rank
属性。 @Noctis的回答建议在更改Rank
值后使用该属性对TreeView
进行排序。我最喜欢的关于这个话题的问题证明了这一点,在这里。
我已经将SortObservableCollection
类添加到我的程序中,所以现在剩下的就是操作排名值和排序。执行此操作的正确位置是从代码隐藏吗?基本上上述^部分是从哪里来的?如果是这样的话,我对确切的电话有点困惑......
代码隐藏:
private void shiftUp_Click(object sender, RoutedEventArgs e)
{
//if a node is selected
if (UCViewModel.TreeViewViewModel.SelectedItem != null)
{
//Moves the selectedNode down one (Up visually, hence shiftUp)
UCViewModel.TreeViewViewModel.SelectedItem.Rank--;
//How would I get the node below the selected one and change the Rank?
//This would be the call to sort. Which needs to be called for the collection
//For some reason, sort does not come up for the collection...
//UCViewModel.TreeViewViewModel.Collection.**Sort(...);
}
}
您可以更改对象等级上的实际值(假设它们是公共属性),而不是实际移动您的项目,并通过绑定自动为您完成排序......
编辑:这很尴尬,正如您的评论所说,我的链接是Winforms。
话虽如此,请看一下瑞秋、WPF-IT 和自我回答的杰里米的精彩回答。
他们要么实现比较器(我使用 msdn 链接的方向),要么使用默认标头。
这应该给你一个很好的开始和如何用你的等级做到这一点的例子。
编辑:
在 Xaml 上:
<StackPanel x:Name="LayoutRoot">
<TreeView Name="TestTreeView" ItemsSource="{Binding MyTree}">
<TreeView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Black" BorderThickness="1" Margin="2" Padding="2">
<TextBlock Text="{Binding Path=Name}"/>
</Border>
</DataTemplate>
</TreeView.ItemTemplate>
</TreeView>
<Button Command="{Binding SortMe_Command}">Sort</Button>
在视图模型上,我有这样的简单类(有等级,适合您):
public class MyTreeClass
{
public string Name { get; set; }
public int Rank { get; set; }
}
我按原样添加了瑞秋的类:
public class SortableObservableCollection<T> : ObservableCollection<T> { ...}
绑定的属性:
public SortableObservableCollection<MyTreeClass> MyTree
{
get { return _myTree; }
set { _myTree = value; }
}
private SortableObservableCollection<MyTreeClass> _myTree;
操作命令:
public ICommand SortMe_Command { get; set; }
在构造函数中:
MyTree = new SortableObservableCollection<MyTreeClass>() {new MyTreeClass(){Name = "One",Rank = 1},
new MyTreeClass(){Name = "Two",Rank = 2},
new MyTreeClass(){Name = "Three",Rank = 3}};
SortMe_Command = new RelayCommand<object>(Execute_SortMe);
SortMe_Command = new RelayCommand<object>(Execute_SortMe);
最后但并非最不重要的一点是,执行方法:
private void Execute_SortMe(object obj)
{
MyTree[0].Rank = 5;
MyTree[1].Rank = 4;
MyTree.Sort(node => node.Rank);
}
现在,当我单击该按钮时,它将更改2个项目的排名,并根据排名重新分配树。
在您的应用程序中,只需找出您要交换的哪一个,您就可以设置...