湖边的白杨树

探索是一种乐趣

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
  218 随笔 :: 1 文章 :: 14 评论 :: 59万 阅读
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

比如需要显示一个键盘,里面有各个按键。实现的效果如下:

 

之前的思路,就是建立一个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>

 

posted on   fdyang  阅读(27727)  评论(1编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
点击右上角即可分享
微信分享提示