【问题标题】:WPF MVVM ViewModel constructor designmodeWPF MVVM ViewModel 构造函数设计模式
【发布时间】:2010-03-23 08:50:37
【问题描述】:

我有一个 WPF 主窗口:

<Window x:Class="NorthwindInterface.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:ViewModels="clr-namespace:NorthwindInterface.ViewModels" Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <ViewModels:MainViewModel />
    </Window.DataContext>
    <ListView ItemsSource="{Binding Path=Customers}">

    </ListView>
</Window>

MainViewModel 是这样的:

class MainViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged = delegate { };

    public MainViewModel()
    {
        Console.WriteLine("test");
        using (NorthwindEntities northwindEntities = new NorthwindEntities())
        {
            this.Customers = (from c in northwindEntities.Customers
                              select c).ToList();
        }
    }

    public List<Customer> Customers { get;private  set; }

现在的问题是,在设计器模式下我看不到我的MainViewModel,它突出显示它说它无法创建MainViewModel 的实例。它正在连接到数据库。这就是为什么(当我评论代码时问题就解决了)。

但我不希望那样。关于这方面的最佳实践的任何解决方案?

以及为什么在使用 MVVM 时这会起作用:

    /// <summary>
    /// Initializes a new instance of the <see cref="MainViewModel"/> class.
    /// </summary>
    public MainViewModel()
    {
        // Just providing a default Uri to use here...
        this.Uri = new Uri("http://www.microsoft.com/feeds/msdn/en-us/rss.xml");
        this.LoadFeedCommand = new ActionCommand(() => this.Feed = Feed.Read(this.Uri), () => true);
        this.LoadFeedCommand.Execute(null); // Provide default set of behavior
    }

它甚至可以在设计时完美执行。

【问题讨论】:

    标签: .net wpf mvvm


    【解决方案1】:

    如果你想在 XAML 中设置 DataContext,你可以在 ViewModel ctor 的顶部使用它:

    if (DesignerProperties.GetIsInDesignMode(new DependencyObject()))
        return;
    

    【讨论】:

      【解决方案2】:

      您可以尝试在后面的代码中设置DataContext,看看是否能解决问题。这几乎完全相同,但也许您的 IDE 只是在发挥作用。

      DataContext = new MainViewModel();
      

      【讨论】:

      • 其实这是完全有效的。 MVVM != 后面没有代码。 MVVM == 在视图中查看关注点。
      • MVVM 并未声明视图中不允许包含任何代码。事实上,许多顶级 MVVM 专家反复说,如果你用 XAML 做一个小时,用代码做 5 分钟,那就用代码做,只要从 View 到 ViewModel 的隔离是没坏所以以上在 MVVM 中是非常可以接受的。并在我的测试中工作:)
      • @Snake:因为在 MVVM 概念中没有这样做 - 宗教在软件设计中永远不会有用。除了您的陈述不正确之外,现实世界的代码通常并不完全符合最严格定义的给定设计模式。
      • Snake 是对的。并不是 MVVM 禁止文件背后的代码中的代码,而是它禁止最小化视图和视图模型之间的耦合。理想情况下,视图应该只通过数据绑定了解视图模型,而不依赖于视图模型的具体类型。在后面的视图代码中实例化具体的视图模型会增加耦合。
      【解决方案3】:

      这将允许您看到设计器。

      public MainViewModel()
      {
          if (!DesignerProperties.IsInDesignTool)
          {
            Console.WriteLine("test");
            using (NorthwindEntities northwindEntities = new NorthwindEntities())
            {
              this.Customers = (from c in northwindEntities.Customers
                                select c).ToList();
            }
          }
      }
      

      【讨论】:

      • A) DesignerProperties.IsInDesignTool 是做什么的? B) 我在 DesignerProperties 下找不到此属性
      • 确实,WPF 调用是不同的。见stackoverflow.com/a/834332/1518546
      【解决方案4】:

      试试这个:

      public MainViewModel()
      {
          if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(new System.Windows.DependencyObject()))
          {
            Console.WriteLine("test");
            using (NorthwindEntities northwindEntities = new NorthwindEntities())
            {
              this.Customers = (from c in northwindEntities.Customers
                            select c).ToList();
            }
          }
      }
      

      【讨论】:

        【解决方案5】:

        ViewModel 没有无参数构造函数时,我看到了这个错误消息。

        【讨论】:

          猜你喜欢
          • 2013-01-02
          • 1970-01-01
          • 2014-10-12
          • 2020-07-18
          • 1970-01-01
          • 2023-03-05
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多