栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > .Net

ContentControl的Content绑定View还是ViewModel

.Net 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

ContentControl的Content绑定View还是ViewModel

一、背景

在WPF中有一种控件叫做ContenControl,其有一个object类型的依赖属性Content。我们常规做法是将UserControl赋值给Content,但是这么做两个问题。

1)一般我们会将Content绑定到ViewModel层的数据,如果该数据为UserControl,那么在ViewModel层中就出现了View层。

2)一般使用Content绑定UserControl的时候,都是用与动态切换的场景,如果我们有比较复杂的UserControl,那么在每一次切换界面的时候都会进行界面的销毁和重新渲染,影响性能。

上述两个问题有解决办法吗?如果我们将ViewModel绑定到Content就可以解决这个问题。

二、实现

那么问题又出现了,如果我们将Content绑定ViewModel,该如何与ViewModel对应的View进行关联呢?

其实在WPF中有一个叫资源的东西,如果我们将数据模板存放在资源中,并且给数据模板指定控件模板,那么我们将Content设置为一个数据模板的时候,其实这个数据模板已经在资源中提前绑定到控件模板上了,所以在界面显示的就是我们的控件模板。

直接上代码:


    
        
    
    
        
            
            
        

        
            
            
            
        

        
    

public class MainViewModel : BaseModel
    {
        public ResourceDictionary Resources { get; set; } = new ResourceDictionary();

        private int selectedIndex;
        public int SelectedIndex
        {
            get { return selectedIndex; }
            set
            {
                selectedIndex = value;
                OnPropertyChanged();
                SetViewModelIndex(value);
            }
        }

        private object viewModelContent;
        public object ViewModelContent
        {
            get{ return viewModelContent; }
            set 
            {
                viewModelContent = value;
                OnPropertyChanged();
            }
        }


        private FrameworkElement window;
        public FrameworkElement Window
        {
            get { return window; }
            set 
            {
                window = value;
                window.Resources = this.Resources;
            }
        }


        private void SetViewModelIndex(int index)
        {
            if (index >= 0 && index < this.models.Count)
                ViewModelContent = this.models[index];
        }


        public MainViewModel()
        {
            this.SetView(new ViewModel1(), typeof(UserControl1));
            this.SetView(new ViewModel2(), typeof(UserControl2));
            this.SetView(new ViewModel3(), typeof(UserControl3));

            SetViewModelIndex(0);
        }

        private List models = new List();
        private void SetView(object viewModel, Type type)
        {
            DataTemplateKey key = new DataTemplateKey(viewModel.GetType());
            DataTemplate template = new DataTemplate(viewModel.GetType());
            template.VisualTree = new FrameworkElementFactory(type);
            this.Resources.Add(key, template);
            this.models.Add(viewModel);
        }
    }
 

上面SetView方法和下面的效果是一致的,,,并且下面的写法感觉更方便。。。


    
        
            
        

        
            
        
    

因为上述ViewModel都是类似的,所以只展示其中一个的代码:

public class Model1
{
     public string FirstName { get; set; }

     public string LastName { get; set; }
}

public class ViewModel1
{
     public List model1s { get; set; } = new List();
     public ViewModel1()
     {
         model1s.Add(new Model1 { LastName = "杨", FirstName = "超越" });
         model1s.Add(new Model1 { LastName = "赵", FirstName = "丽颖" });
         model1s.Add(new Model1 { LastName = "刘", FirstName = "诗诗" });
         model1s.Add(new Model1 { LastName = "高", FirstName = "圆圆" });
     }
}

    
        
            
                
                    
                        
                        
                    
                
            
        
    

三、效果

四、总结

上述方法在每一次切换ViewModel的时候,都会去找它对应的View,也就意味着每一次的都会重新实例化一个View对象。因为ViewModel对象没有变化并且绑定到了View,所以View层也好像没有改变一样,但其实是重新实例化了一个对象。这里感觉有点依赖注入的意思,现在我们期望管理依赖对象的生命周期,如果没有办法做到这一点,这种方式应该也不是很友好。。。。。除非你做到了真正意义的MVVM,在View层并没有多余的信息,不然这样使用是有问题的

  1. 每次切换都会重新实例化View层,消耗资源
  2. 如果View层有数据,那么每一次都会复原,不会像在ViewModel层中的数据一样复原到新实例化的View层
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号