好比須要顯示一個鍵盤,裏面有各個按鍵。實現的效果以下:app
以前的思路,就是創建一個singleKey的控件,而後在後臺用代碼動態的添加到父控件裏去, 再用代碼在後臺進行綁定。mvvm
這種實現方法並非真正的MVVM的模式。體會不到MVVM帶來的便捷和驚喜。ui
用MVVM模式來實現時的思路以下:this
1. 創建singleKey的ViewModel,定義須要綁定View的屬性。spa
2. 在Key的ViewModel中,使用可觀察集合,並綁定到View的ItemsSource上。code
ViewModelblog
public ObservableCollection<DutSingleKeyViewModel> Keysets { get { return this.keysets; } set { this.keysets = value; } }
3. 對於singleKey的顯示,能夠在DataTemplat裏面定義。rem
Viewget
<UserControl.DataContext> <vm:DutKeysetViewModel /> </UserControl.DataContext> <UserControl.Resources> <DataTemplate DataType="{x:Type vm:DutSingleKeyViewModel}"> <Canvas> <Grid Canvas.Left="{Binding KeyLocationLeft, Mode=OneWay}" Canvas.Top="{Binding KeyLocationTop, Mode=OneWay}" > <Rectangle Fill="#FFF4F4F5" HorizontalAlignment="Left" Width="{Binding KeySizeWidth}" Height="{Binding KeySizeHeight}" Stroke="Black" VerticalAlignment="Top"></Rectangle> <TextBlock HorizontalAlignment="Left" TextWrapping="Wrap" Text="{Binding KeyCharacter}" Margin="5,0,0,0" VerticalAlignment="Top" /> </Grid> </Canvas> </DataTemplate> </UserControl.Resources> <Grid> <WrapPanel HorizontalAlignment="Left" Height="227" Width="532"> <ItemsControl ItemsSource="{Binding Keysets}"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Orientation="Horizontal" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> </ItemsControl> </WrapPanel>
因而,並不用在後臺寫過多的代碼,修改ViewModel後, View的顯示就相應變動了。it
補充網上大牛的回覆。
if you really want to do mvvm , try to forget "how can i add controls". you dont have to, just think about your viewmodels - WPF create the contols for you :)
in your case lets say we have a SearchViewModel and a SearchEntryViewmodel.
public class SearchEntryViewmodel { //Properties for Binding to Combobox and Textbox goes here } public class SearchViewModel { public ObservableCollection<SearchEntryViewmodel> MySearchItems {get;set;} public ICommand AddSearchItem {get;} }
till now you dont have to think about usercontrols/view. in your SearchView you create an ItemsControl and bind the ItemsSource to MySearchItems.
<ItemsControl ItemsSource="{Binding MySearchItems}"/>
you see now all of your SearchEntryViewmodels in the ItemsControl(just the ToString() atm).
To fit your requirements to show every SearchEntryViewmodel with 3Comboboxes and so on you just have to define a DataTemplate in your Resources
<DataTemplate DataType="{x:Type local:SearchEntryViewmodel}"> <StackPanel Orientation="Horizontal"> <Combobox ItemsSource="{Binding MyPropertyInSearchEntryViewmodel}"/> <!-- the other controls with bindings --> </StackPanel> </DataTemplate>
thats all :) and you never has to think about how can i add controls dynamically. you just have to add new SearchEntryViewmodel to your collection.
this approach is called Viewmodel First and i think its the easiest way to do MVVM.
在實踐發現,通用的方法仍是建立一個userControl view,重要的是再DataTemplate裏面引用:
<Window.Resources> <DataTemplate DataType={x:Type viewmodels:MyUserControlViewModel}"> <views:MyUserControlView /> </DataTemplate> </Window.Resources>