2013-02-17 52 views
1

我希望用戶能夠在10個或更多個唯一UserControl之間進行選擇,並以任意順序將任何UserControl的任意數量的多個實例顯示在列表中。因此,該列表可能看起來像這樣的UC1,UC1,UC3,UC3,UC10,UC8等。重要的是要注意,前面示例中的兩個UC1和兩個UC3是具有與它們相關聯的不同值的不同實例。基本上,我創建了一系列命令,我將解析爲一個真實世界的操作。將ListView中的多個唯一UserControl綁定到ObservableCollection

問題:我無法將顯示在ListView中的UserControls綁定到ObservableCollection中的數據。至少,我在UserControls中的綁定是錯誤的,我不知道如何讓它們工作。

我正在使用MVVMLight。我有一個窗口控件只包含一個內容控件,它具有一個名爲CommandView的UserControl,這是我的主要顯示。 CommandView目前有幾個按鈕,其屬性綁定到CommandViewModel中的繼電器命令,這些命令將唯一的類實例添加到名爲CommandsCollection的ObservableCollection中。 ListView綁定到封裝CommandsCollection的屬性。

我在後面的代碼中使用DataTemplate和DataTemplateSelector,根據集合中該位置的類的類型選擇正確的UserControl(UC1,UC2等)。我已經成功地工作了,但是我沒有將顯示的UserControl文本框綁定回ObservableCollection,所以沒有數據顯示在UserControl的文本框中。我確實在ObservableCollection中設置了類屬性的默認值,並將集合寫入文本文件,並查看這些值是默認值。所以ObservableCollection正在看到這些值。

如何在用戶控件中設置綁定?下面是我在UC1用戶控制:

<lightext:UserControl 
DataContext="{Binding VelocityCommandStatic, Source={StaticResource Locator}}"> 

<TextBox Text="{Binding VelocityCommandProperty.VelocityKinematic, 
     UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/> 

VelocityCommandStatic - 我其實是有點困惑是這個爲好,但這是在viewmodellocator.cs創建的用戶控件的對象(?)。

什麼是綁定的最佳方式? xaml綁定點是否可以直接返回到ObservableCollection?有一個問題,每個UserControl具有不同的屬性,並且我爲該集合中的每個用戶控件放置了不同的類(實例)。我會知道這些屬性,但需要在xaml中正確設置它們。也許這種方法並不理想。我可以在視圖模型中將UserControl點的屬性返回到CommandViewViewModel的observablecolleciton中的正確位置嗎?

回答

2

看,你太過於複雜了。所有你需要的是一個ObservableCollection,它可以容納你所有的物品和一個適當的DataTemplate。不需要DataTemplateSelectors或任何其他類似的東西。此外,還有沒有必要point directly back to the ObservableCollection,這意味着什麼:

主窗口:

<Window x:Class="WpfApplication5.Window3" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:local="clr-namespace:WpfApplication5" 
     Title="Window3" Height="300" Width="300"> 
    <Window.Resources> 
     <DataTemplate DataType="{x:Type local:Item1}"> 
      <local:UserControl1/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type local:Item2}"> 
      <local:UserControl2/> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type local:Item3}"> 
      <local:UserControl3/> 
     </DataTemplate> 
    </Window.Resources> 
    <ListBox ItemsSource="{Binding}"/> 
</Window> 

代碼背後:

using System.Collections.Generic; 
using System.Collections.ObjectModel; 
using System.Windows; 
using System.ComponentModel; 

namespace WpfApplication5 
{ 
    public partial class Window3 : Window 
    { 
     public Window3() 
     { 
      InitializeComponent(); 

      DataContext = new ObservableCollection<ItemBase> 
       { 
        new Item1() {MyText1 = "This is MyText1 inside an Item1"}, 
        new Item2() {MyText2 = "This is MyText2 inside an Item2"}, 
        new Item3() {MyText3 = "This is MyText3 inside an Item3", MyBool = true} 
       }; 
     } 
    } 

    public class ItemBase: INotifyPropertyChanged 
    { 
     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void NotifyPropertyChange(string propertyName) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName)); 
     } 
    } 

    public class Item1: ItemBase 
    { 
     private string _myText1; 
     public string MyText1 
     { 
      get { return _myText1; } 
      set 
      { 
       _myText1 = value; 
       NotifyPropertyChange("MyText1"); 
      } 
     } 
    } 

    public class Item2: ItemBase 
    { 
     private string _myText2; 
     public string MyText2 
     { 
      get { return _myText2; } 
      set 
      { 
       _myText2 = value; 
       NotifyPropertyChange("MyText2"); 
      } 
     } 

     private ObservableCollection<string> _options; 
     public ObservableCollection<string> Options 
     { 
      get { return _options ?? (_options = new ObservableCollection<string>()); } 
     } 

     public Item2() 
     { 
      Options.Add("Option1"); 
      Options.Add("Option2"); 
      Options.Add("Option3"); 
      Options.Add("Option4"); 
     } 
    } 

    public class Item3: ItemBase 
    { 
     private string _myText3; 
     public string MyText3 
     { 
      get { return _myText3; } 
      set 
      { 
       _myText3 = value; 
       NotifyPropertyChange("MyText3"); 
      } 
     } 

     private bool _myBool; 
     public bool MyBool 
     { 
      get { return _myBool; } 
      set 
      { 
       _myBool = value; 
       NotifyPropertyChange("MyBool"); 
      } 
     } 
    } 
} 

的UserControl1:

<UserControl x:Class="WpfApplication5.UserControl1" 
      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" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Border BorderBrush="Black" BorderThickness="1"> 
     <StackPanel> 
      <TextBlock Text="This is UserControl1"/> 
      <TextBlock Text="{Binding MyText1}"/> 
     </StackPanel> 
    </Border> 
</UserControl> 

UserControl2:

<UserControl x:Class="WpfApplication5.UserControl2" 
      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" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Border BorderBrush="Black" BorderThickness="1"> 
     <StackPanel> 
      <TextBlock Text="This is UserControl2"/> 
      <TextBox Text="{Binding MyText2}"/> 
      <ComboBox ItemsSource="{Binding Options}" SelectedItem="{Binding MyText2}"/> 
     </StackPanel> 
    </Border> 
</UserControl> 

UserControl3:

<UserControl x:Class="WpfApplication5.UserControl3" 
      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" 
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"> 
    <Border BorderBrush="Black" BorderThickness="1"> 
     <StackPanel> 
      <TextBlock Text="This is UserControl3"/> 
      <TextBlock Text="{Binding MyText3}"/> 
      <CheckBox Content="This is the MyBool Property" IsChecked="{Binding MyBool}"/> 
     </StackPanel> 
    </Border> 
</UserControl> 

只需複製並粘貼我的代碼在一個文件 - 新建 - WPF應用程序,看看效果如何。它看起來像這樣:

enter image description here

+0

我複製你的代碼,並有工作 - 你說得對,我確實有它過於複雜。我試着不說我花了多少時間研究我的非工作解決方案,但是它是很多的。這真的很棒 - 我非常感謝 - 謝謝!我會把它編入我的程序並嘗試。 – FloppyDisk 2013-02-17 19:38:15

相關問題