【问题标题】:How to apply MVVM Pattern in this model?如何在这个模型中应用 MVVM 模式?
【发布时间】:2011-11-10 19:45:18
【问题描述】:

问题从这个帖子开始:Using binding to a List<UserControl> how can I do for not showing the controls

我正在设计这样的东西:

List<Container>
(Below container properties)
    - Objective: string
    - Problems: List<ProblemUserControl>

ProblemUserControls 是一个 UserControl,其中包含一个名为 Problem 的额外属性。但是上面的帖子有人建议我使用 MVVM Pattern。我正在调查,但我仍然感到困惑,或者我需要一些帮助来理解 WPF 中的模式。

【问题讨论】:

标签: c# wpf design-patterns


【解决方案1】:

这里有一个例子来说明如何使用 MVVM。请注意,不需要有用户控件列表,从 MVVM 的角度来看,这确实被认为是不正确的。

这是基于 Visual Studio 中默认的 WPF 应用程序模板。

这里是涉及的类。

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler changed = PropertyChanged;
        if (changed != null)
        {
            changed(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

public class Container : ViewModelBase
{
    private string m_Objective;
    private ProblemCollection m_Problems;

    public Container()
    {
        m_Problems = new ProblemCollection();
    }

    public string Objective
    {
        get { return m_Objective; }
        set
        {
            m_Objective = value;
            OnPropertyChanged("Objective");
        }
    }

    public ProblemCollection Problems
    {
        get { return m_Problems; }
        set
        {
            m_Problems = value;
            OnPropertyChanged("Problems");
        }
    }
}

public class Problem : ViewModelBase
{
    private string m_Name;

    public string Name
    {
        get { return m_Name; }
        set
        {
            m_Name = value;
            OnPropertyChanged("Name");
        }
    }
}

public class ProblemCollection : ObservableCollection<Problem>
{
}

还有主窗口。请注意,我已注释掉您的矩形以显示绑定

<Window x:Class="StackOverflowDemo.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525">
  <Grid>
    <TextBlock TextWrapping="Wrap" Text="{Binding Objective}" Grid.Column="0" VerticalAlignment="Center"
        FontWeight="Bold" />
    <ItemsControl ItemsSource="{Binding Problems}">
      <ItemsControl.ItemTemplate>
        <DataTemplate>
          <!--<Rectangle Stroke="Black" Height="20" Width="20" Margin="1,0" />-->
          <TextBlock Text="{Binding Path=Name}" />
        </DataTemplate>
      </ItemsControl.ItemTemplate>
    </ItemsControl>
  </Grid>
</Window>

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        // Create dummy test data.
        // Normally this will be passed to the window or set externally
        var container = new Container();
        container.Problems.Add(new Problem {Name = "Foo"});
        container.Problems.Add(new Problem {Name = "Bar"});
        container.Problems.Add(new Problem {Name = "hello"});
        container.Problems.Add(new Problem {Name = "world"});

        DataContext = container;
    }
}

【讨论】:

    【解决方案2】:

    该模式是关于维护软件逻辑层之间的适当分离和依赖关系。您在示例中将显示逻辑与业务逻辑混淆了,因为您将模型代码(目标容器)与显示代码(用户控件列表)混合在一起。

    相反,保持你的目标并保持List&lt;Problem&gt; 而不是List&lt;ProblemUserControl&gt;。然后使用 WPF 和绑定将您的ProblemUserControlProblem 关联。您的用户控件了解Problem 是什么,因此您可以绑定Problem 上的属性。通过这种方式,您可以分离您的层,并且更容易对您的软件进行总体推理。

    【讨论】:

    • 格雷格,我想我明白你想告诉我什么。但我不知道如何开始构建应用程序
    • 一步一步。这里没有灵丹妙药:开始做吧,犯错误,然后从中学习。
    猜你喜欢
    • 2015-06-14
    • 1970-01-01
    • 1970-01-01
    • 2014-05-27
    • 1970-01-01
    • 2018-09-04
    • 1970-01-01
    • 1970-01-01
    • 2023-04-03
    相关资源
    最近更新 更多