C# WPF/Silverlight:如何将基于ItemsControl的UI元素绑定到ViewModel上的ItemsControl属性?

C# WPF/Silverlight:如何将基于ItemsControl的UI元素绑定到ViewModel上的ItemsControl属性?,c#,wpf,mvvm,binding,itemscontrol,C#,Wpf,Mvvm,Binding,Itemscontrol,作为WPF/XAML/MVVM的新手,我有一个问题 在我看来,我有两个列表框,它们来自ItemsControl。 在我的viewmodel上,我想公开2个ItemsControl属性,这样我就可以将我的listbox绑定到此视图模型属性。。。通过这种方式,我可以从视图模型实现一个命令,该命令允许我将当前选定的项从ListBox1移动到ListBox2 想象一下,下面的片段中没有显示所有真正酷的东西: 查看模型代码: public int MyStuff1SelectedIndex { get{.

作为WPF/XAML/MVVM的新手,我有一个问题

在我看来,我有两个列表框,它们来自ItemsControl。 在我的viewmodel上,我想公开2个ItemsControl属性,这样我就可以将我的listbox绑定到此视图模型属性。。。通过这种方式,我可以从视图模型实现一个命令,该命令允许我将当前选定的项从ListBox1移动到ListBox2

想象一下,下面的片段中没有显示所有真正酷的东西:

查看模型代码:

public int MyStuff1SelectedIndex { get{...} set{...} }
public int MyStuff2SelectedIndex { get{...} set{...} }
public ItemsControl MyStuffItemsControl1 { set; private get; }
public ItemsControl MyStuffItemsControl2 { set; private set; }
查看XAML:

   <ListBox Name="x:MyStuffListBox1" SelectedIndex="{Binding MyStuff1SelectedIndex}.... />
   <ListBox Name="x:MyStuffListBox2" SelectedIndex="{Binding MyStuff2SelectedIndex}...../>
那么,基本上,绑定XAML是什么样子的呢?我正在尝试从视图设置视图模型的属性


谢谢

您需要重新考虑这种方法。通常,您会将两个ListBox项Source属性绑定到视图模型上的两个
ObservableCollection
属性,其中T是列表中的对象类型

<ListBox x:Name="MyStuffListBox1" ItemsSource="{Binding MyList1}" SelectedItem="{Binding SelectedList1Item}" />
<ListBox x:Name="MyStuffListBox2" ItemsSource="{Binding MyList2}" SelectedItem="{Binding SelectedList2Item}" />

注意:我会在XAML中使用x:Name,而不是Name属性

public ObservableCollection<Thing> MyList1 { get; set; }
public ObservableCollection<Thing> MyList2 { get; set; }

// these properties should raise property changed events (INotifyPropertyChanged)
public Thing SelectedList1Item { get {...} set {...} }
public Thing SelectedList2Item { get {...} set {...} }

// constructor 
public MyViewModel()
{
  // instantiate and populate lists
  this.MyList1 = new ObservableCollection(this.service.GetThings());
  this.MyList2 = new ObservableCollection(this.service.GetThings());
} 
publicobservableCollection MyList1{get;set;}
公共ObservableCollection MyList2{get;set;}
//这些属性应引发属性更改事件(INotifyPropertyChanged)
public Thing SelectedList1Item{get{…}set{…}
public Thing SelectedList2Item{get{…}set{…}
//建造师
公共MyViewModel()
{
//实例化并填充列表
this.MyList1=newobserveCollection(this.service.GetThings());
this.MyList2=新的ObservableCollection(this.service.GetThings());
} 
然后,您可以使用DisplayMemberPath或在每个列表上定义ItemTemplate格式化列表中显示的内容


您可以使用ObservableCollection类型上的标准收集方法在列表之间交换项-

您不应该在视图模型中实现控件。这使它成为一个视图,而不是视图的模型。视图模型上的属性应该是
ObservableCollection
,并且应该将items控件的
ItemsSource
绑定到这些属性

如果执行此操作,您的XAML可能如下所示:

<ListBox ItemsSource="{Binding List1}" SelectedItem="{Binding SelectedItem1, Mode=TwoWay}"/>
<ListBox ItemsSource="{Binding List2}" SelectedItem="{Binding SelectedItem2, Mode=TwoWay}"/>
<Button Command="{Binding MoveItemFromList1ToList2Command}">Move</Button>

我必须测试这段代码才能确定,但我认为您不需要在
MoveItemFromList1ToList2
方法中处理属性更改通知;当您从
列表1
中删除该项时,
可观察集合
将通知
列表框
该项已被删除,
列表框
SelectedItem
设置为null,更新视图模型中的
SelectedItem1
。(当然,如果在将其添加到第二个集合之前将其从第一个集合中删除,则会导致代码中断。)

感谢Rob/devdigital的回复。我已经有了ObservableCollection属性用作ItemSource,以及viewmodel上的属性
我想我的问题是,如果没有对UI控件的引用,如何将项目从一个列表框移动到另一个列表框
你没有。您将它从一个集合移动到另一个集合,数据绑定会为您更新列表框。谢谢,我现在意识到了这一点。比我的黑客尝试简单多了。
<ListBox ItemsSource="{Binding List1}" SelectedItem="{Binding SelectedItem1, Mode=TwoWay}"/>
<ListBox ItemsSource="{Binding List2}" SelectedItem="{Binding SelectedItem2, Mode=TwoWay}"/>
<Button Command="{Binding MoveItemFromList1ToList2Command}">Move</Button>
public bool CanMoveItemFromList1ToList2
{
   { get { return SelectedItem1 != null; }
}

public void MoveItemFromList1ToList2()
{
   List2.Add(SelectedItem1);
   List1.Remove(SelectedItem1);
}