我有一个包含UserControl的MainWindow,它们都是用MVVM模式实现的.
MainWindowVM具有我想要绑定到UserControl1VM中的属性的属性.但这不起作用.
MainWindowVM具有我想要绑定到UserControl1VM中的属性的属性.但这不起作用.
这里是一些代码(viewmodels使用某种mvvm框架,在viewmodelBase类中实现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>
CodeBehind MainWindow.xaml.cs:
- 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>
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:
- 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.
我究竟做错了什么?
首先,如果要从外部绑定它,则需要在UserControl1中声明DependencyProperty TextInControl.
在UserControl1中移动DP的声明.
- 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(UserControl1));
- }
其次,你将UserControl的DataContext外部设置为UserControl1VM,
- public UserControl1()
- {
- InitializeComponent();
- DataContext = new UserControl1VM(); <-- HERE (Remove this)
- }
所以WPF绑定引擎在UserControl1VM中寻找属性Text而不是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上设置x:Name,使用ElementName绑定DP.
UPDATE
如果您希望UserControl的viewmodel完好无损,则必须更新MainWindow中的绑定.显式告诉WPF绑定引擎在MainWindow的DataContext中使用ElementName查找属性,如下所示:
- <local:UserControl1 TextInControl="{Binding DataContext.Text,ElementName=mainWindow}" />
为此,您需要在窗口根级别设置x:Name =“mainWindow”.