2010-12-22 61 views
0

作爲WPF/XAML/MVVM的新手,我有一個問題。WPF/Silverlight:如何將基於ItemsControl的UI元素綁定到ViewModel上的ItemsControl屬性?

在我看來,我有2個列表框,從ItemsControl派生。 在我的viewmodel上,我想公開兩個ItemsControl屬性,這樣我就可以將我的列表框綁定到這個視圖模型屬性......這樣我就可以實現一個命令,從視圖模型中,我可以移動當前選定的項目從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}...../> 

鑑於此,我希望我的視圖模型是能夠有一個命令可以將項目從一個列表框移動到另一個列表框,具有以下代碼:

public void MoveItemCommandExecute(...) 
{ 
    var sourceItem = MyStuff1ItemsControl.MagicGetItemExtensionMehod(MyStuff1SelectedIndex); 
    MyStuff1ItemsControl.MagicRemoveItemExtensionMethod(MyStuff1SelectedIndex); 

    MyStuff2ItemsControl.MagicAddItemExtensionMethod(sourceItem); 
} 

那麼,基本上,綁定XAML是什麼樣子?我試圖從視圖上設置視圖模型的屬性...

謝謝!

回答

1

你會想重新考慮這種方法。通常,您會將兩個列表框的ItemsSource屬性綁定到視圖模型上的兩個ObservableCollection<T>屬性,其中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()); 
} 

然後,您可以格式化什麼用的DisplayMemberPath或每個列表定義一個ItemTemplate顯示在列表中。

您可以通過使用對的ObservableCollection類型的標準集合方法交換列表之間的項目 - http://msdn.microsoft.com/en-us/library/ms668604.aspx

0

你不應該在你的視圖模型來實施控制。這使它成爲一種觀點,而不是一種觀點的模型。視圖模型上的屬性應爲ObservableCollection<T>,並且您應該將項目控件的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> 

List1List2ObservableCollection<T>類型,SelectedItem1SelectedItem2T型(無論何種類型,你已經決定T應)的,和MoveItemFromList1ToList2Command是定義有兩種處理一個RoutedCommand

public bool CanMoveItemFromList1ToList2 
{ 
    { get { return SelectedItem1 != null; } 
} 

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

我不得不TES這個代碼是肯定的,但我不認爲你需要打擾MoveItemFromList1ToList2方法中的財產變更通知;當您從List1中刪除該項目時,ObservableCollection將通知ListBox該項目已被刪除,並且ListBox將設置SelectedItem爲空,更新視圖模型中的SelectedItem1。 (當然,如果在將其添加到第二個集合中之前將其從第一個集合中刪除,那麼這會使代碼中斷)。

+0

感謝Rob/devdigital的回覆。我已經有了ObservableCollection屬性作爲ItemSource和viewmodel的屬性。
我想我的問題是如何我可以將一個項目從一個列表框移動到另一個列表框,如果我沒有對UI控件的引用。
Wes 2010-12-23 08:59:32

相關問題