首页 > 解决方案 > 使用 Caliburn Micro 绑定到 VM 时无法将子项添加到 Grid

问题描述

我想在我的 Caliburn.Micro 应用程序中从我的视图模型中将(任何)元素添加到网格中(它实际上是一个 Revit 插件,所以不完全是一个应用程序,但应该可以正常工作)。

我很难理解 MVVM 模型的某些方面并将数据绑定到视图中的元素......

我的视图模型

public class MyViewModel : Screen
{
    private Grid _myGrid;
    public Grid MyGrid
    {
        get { return _myGrid; }
        set
        {
            _myGrid = value;
            NotifyOfPropertyChange(() => MyGrid);
        }
    }

    public MyViewModel()
    {
        MyGrid = new Grid();
        var label = new Label { Content = "Hello!" };
        MyGrid.Children.Add(label); // I know this isn't MVVM but how can I do basically this?
    }
}

我的观点

<Window x:Class="MyProject.MyView"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:cal="http://www.caliburnproject.org"
        xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
        xmlns:local="clr-namespace:MyProject.Views"
        mc:Ignorable="d">

    <Grid x:Name="MyGrid">
        <!-- Here goes stuff from view model -->
    </Grid>
</Window>

我知道这都是错误的......我需要帮助将元素从视图模型中放入我的网格元素中。

标签: c#wpfmvvmcaliburn.micro

解决方案


您在此处采用的一般方法是错误的,因为您在 ViewModel 中创建 View 元素。使用 MVVM,您仍然希望在 XAML 中设计您的 UI(视图)。在您的情况下,在大多数情况下,您仍然会在 XAML 中创建Grid和。Label想想你在用这种方法做什么。

您有一个存储数据属性并通知更改的数据模型。将此视为数据的结构方面。

public class MyModel : INotifyPropertyChanged
{
    private string labelValue;
    public string LabelValue
    {
        get { return labelValue; }
        set
        {
            labelValue = value;
            NotifyOfPropertyChange(() => LabelValue);
        }
    }

    //Property changed handler logic below.
    //I assume you have something based on your code.
}

现在我们创建一个 ViewModel 来处理数据。这也是视图绑定的内容。

public class MyViewModel
{
    //Add a property for the model you created
    public MyModel NewModel {get;set;}

    //Load the NewModel values when the view model is created.
    public MyViewModel()
    {
        NewModel = new MyModel(){LabelValue="Hello World"};
    }
}

好的,所以我们有一个数据Model,我们有一个ViewModel实际使用Model并用值填充它。现在让我们创建 UI ( View) 并绑定到ViewModel.

在您Window中,您将创建一个标签并简单地绑定您想要的ViewModel属性。在这种情况下,我们将您的模型LabelValue属性。

<Grid>
     <Label Content="{Binding NewModel.LabelValue}"/>
</Grid>

现在我们只需在 UI 代码隐藏中设置数据上下文

public MyViewModel myViewModel = new MyViewModel(); //Create the ViewModel
public MyWindow()
{
     InitializeComponent();  
     //Set the DataContext to the ViewModel
     DataContext = myViewModel;
}

当您启动程序时,标签内容应该是您在ViewModel MyModel.LabelValue属性中设置的任何内容。这只是对非常大的概念的简单解释,但它应该让您了解它是如何工作的。人们使用的 MVVM 技术和风格也有很多,但这个概念是 MVVM 最基本的形式。希望这能给你一个想法,让你走上正确的道路。

目标是在你身上运行你的逻辑,ViewModel以便可以用最少的代码构建Views 和s。Model如果您在没有额外代码或 UI 线程锁的情况下正确实现自动更新的INotifyPropertyChanged所有值。View尽管这个概念起初看起来很庞大,但从长远来看,它可以节省大量时间和精力。


推荐阅读