(WPF) MVVM: 動態添加控件及綁定。


比如需要顯示一個鍵盤,里面有各個按鍵。實現的效果如下:

 

之前的思路,就是建立一個singleKey的控件,然后在后台用代碼動態的添加到父控件里去, 再用代碼在后台進行綁定。

這種實現方法並不是真正的MVVM的模式。體會不到MVVM帶來的便捷和驚喜。

用MVVM模式來實現時的思路如下:

1. 建立singleKey的ViewModel,定義需要綁定View的屬性。

2. 在Key的ViewModel中,使用可觀察集合,並綁定到View的ItemsSource上。

ViewModel

        public ObservableCollection<DutSingleKeyViewModel> Keysets
        {
            get
            {
                return this.keysets;
            }
            set
            {
                this.keysets = value;
            }
        }  

 

3. 對於singleKey的顯示,可以在DataTemplat里面定義。

View

 <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的顯示就相應變更了。

 

補充網上大牛的回復。

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>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM