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

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

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>

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

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:
<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的代码:
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:
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));
    }
}

有了这个星座,在MainWindow.xaml中就找不到DP。

我究竟做错了什么?

最佳答案

如果要从外部绑定(bind)DependencyProperty TextInControl,请在UserControl1内部声明所有首个

将DP的声明移到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
    public UserControl1()
    {
        InitializeComponent();
        DataContext = new UserControl1VM(); <-- HERE (Remove this)
    }

因此,WPF绑定(bind)引擎在Text而不是UserControl1VM中寻找属性MainWindowVM。删除设置DataContext并将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"
             x:Name="userControl1">
    <Grid>
        <TextBlock Text="{Binding TextInTextBlock, ElementName=userControl1}" />
    </Grid>
</UserControl>

通过在UserControl上设置ElementName,使用x:Name绑定(bind)DP。

更新

如果您想完整保留ViewModelUserControl,则必须在MainWindow中更新绑定(bind)。明确告诉WPF绑定(bind)引擎在绑定(bind)中使用ElementName在MainWindow的DataContext中查找属性,如下所示:
<local:UserControl1 TextInControl="{Binding DataContext.Text,
                    ElementName=mainWindow}" />

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

关于wpf - 绑定(bind)UserControl依赖项属性和MVVM,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22247633/

10-11 00:51
查看更多