我有一个包含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。更新
如果您想完整保留
ViewModel
的UserControl
,则必须在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/