绑定UserControl依赖属性和MVVM [英] Binding UserControl Dependency Property and MVVM

查看:95
本文介绍了绑定UserControl依赖属性和MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含UserControl的MainWindow,两者均以MVVM模式实现。
MainWindowVM具有要绑定到UserControl1VM中的属性的属性。但这行不通。

I have a MainWindow containing a UserControl, both implemented in MVVM-pattern. The MainWindowVM has properties that I want to bind to properties in the UserControl1VM. But this doesn't work.

这里是一些代码(视图模型使用某种mvvm-framework在ViewModelBase类中实现INotifyPropertyChanged,但希望这没问题):

Here's some code (the viewmodels use some kind of mvvm-framework that implement the INotifyPropertyChanged in a ViewModelBase-class but that's hopefully no problem):

MainWindow.xaml:

MainWindow.xaml:

<Window x:Class="DPandMVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DPandMVVM"
    Title="MainWindow" Height="300" Width="300">
    <Grid>
        <local:UserControl1 TextInControl="{Binding Text}" />
    </Grid>
</Window>

CodeBehind MainWindow.xaml.cs:

CodeBehind MainWindow.xaml.cs:

using System.Windows;
namespace DPandMVVM
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            DataContext = new MainWindowVM();
        }
    }
}

MainWindow-ViewModel MainWindowVM.cs :

MainWindow-ViewModel MainWindowVM.cs:

namespace DPandMVVM
{
    public class MainWindowVM : ViewModelBase
    {
        private string _text;
        public string Text { get { return _text; } }

        public MainWindowVM()
        {
            _text = "Text from MainWindowVM";
        }
    }
}

这里是UserControl1.xaml :

And here the UserControl1.xaml:

<UserControl x:Class="DPandMVVM.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <TextBlock Text="{Binding TextInTextBlock}" />  
    </Grid>
</UserControl>

UserControl1.xaml.cs的代码隐藏:

The Codebehind UserControl1.xaml.cs:

using System.Windows.Controls;    
namespace DPandMVVM
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public UserControl1()
        {
            InitializeComponent();
            DataContext = new UserControl1VM();
        }
    }
}

和Viewmodel UserControl1VM.cs :

And the Viewmodel UserControl1VM.cs:

using System.Windows;    
namespace DPandMVVM
{
    public class UserControl1VM : DependencyObject
    {
        public UserControl1VM()
        {
            TextInControl = "TextfromUserControl1VM";
        }

        public string TextInControl
        {
            get { return (string)GetValue(TextInControlProperty); }
            set { SetValue(TextInControlProperty, value); }
        }

        public static readonly DependencyProperty TextInControlProperty =
            DependencyProperty.Register("TextInControl", typeof(string), typeof(UserControl1VM));
    }
}

有了这个星座,DP无法在MainWindow中找到。 xaml。

With this constellation the DP cannot be found in MainWindow.xaml.

我在做什么错了?

推荐答案

要想将DependencyProperty TextInControl 声明在 UserControl1 中,首先要在其中进行依赖

First of all you want DependencyProperty TextInControl to be declared inside UserControl1 if you want to bind it from outside.

将DP的声明移至 UserControl1 内部。

Move the declaration of DP inside of UserControl1.

public partial class UserControl1 : UserControl
{
    public UserControl1()
    {
        InitializeComponent();
    }

    public string TextInControl
    {
        get { return (string)GetValue(TextInControlProperty); }
        set { SetValue(TextInControlProperty, value); }
    }

    public static readonly DependencyProperty TextInControlProperty =
        DependencyProperty.Register("TextInControl", typeof(string), 
                                       typeof(UserControl1));
}






第二,您已将UserControl的DataContext外部设置为 UserControl1VM


Second you have externally set DataContext of UserControl to UserControl1VM,

    public UserControl1()
    {
        InitializeComponent();
        DataContext = new UserControl1VM(); <-- HERE (Remove this)
    }

因此WPF绑定引擎正在寻找属性 UserControl1VM 中的文本,而不是 MainWindowVM 。删除设置DataContext并将UserControl1的XAML更新为:

So WPF binding engine looking for property Text in UserControl1VM instead of MainWindowVM. Remove setting DataContext and update XAML of UserControl1 to this:

<UserControl x:Class="DPandMVVM.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             x:Name="userControl1">
    <Grid>
        <TextBlock Text="{Binding TextInTextBlock, ElementName=userControl1}" />  
    </Grid>
</UserControl>

使用 ElementName 设置<$来绑定DP c $ c> x:Name 在UserControl上。

Bind DP using ElementName by setting x:Name on UserControl.

更新

如果您想为 UserControl ViewModel c>,您必须在MainWindow中更新绑定。明确告诉WPF绑定引擎在绑定中使用 ElementName 在MainWindow的DataContext中查找属性,如下所示:

In case you want to have ViewModel intact for UserControl, you have to update binding in MainWindow. Explicitly tell WPF binding engine to look for property in MainWindow's DataContext using ElementName in binding like this:

<local:UserControl1 TextInControl="{Binding DataContext.Text,
                    ElementName=mainWindow}" />

为此,您需要设置 x:Name = mainWindow 在窗口根目录级别。

For this you need to set x:Name="mainWindow" on window root level.

这篇关于绑定UserControl依赖属性和MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆