wpf - ViewModel 数据不会以独占方式绑定到 UserControl
问题描述
我的 MainWindow 有一个简单的测试 ViewModel:
namespace MyApp.ViewModels
{
class MainWindowViewModel : ViewModelBase
{
public string Test { get; set; } = "TEST";
}
}
没有比这更简单的了。现在我提供有关它的 MainWindow 知识并将 Test 属性绑定到 TextBox 和自己的 UserControl:
<Window x:Class="MyApp.MainWindow"
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:local="clr-namespace:MyApp"
xmlns:uc="clr-namespace:MyApp.UserControls"
xmlns:vm="clr-namespace:MyApp.ViewModels"
mc:Ignorable="d"
Width="800"
Height="600">
<Window.DataContext>
<vm:MainWindowViewModel />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBox HorizontalAlignment="Left"
Grid.Row="0"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"
Text="{Binding Test, PresentationTraceSources.TraceLevel=High}" />
<uc:TestUserControl Grid.Row="1" Test="{Binding Test, PresentationTraceSources.TraceLevel=High}" />
</Grid>
</Window>
再次,非常简单。
我的 TestUserControl 看起来像这样:
<UserControl x:Class="MyApp.UserControls.TestUserControl"
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"
xmlns:local="clr-namespace:MyApp.UserControls"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox HorizontalAlignment="Left"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"
Text="{Binding Test, PresentationTraceSources.TraceLevel=High}" />
</Grid>
</UserControl>
namespace MyApp.UserControls
{
public partial class TestUserControl : UserControl
{
public static readonly DependencyProperty TestProperty =
DependencyProperty.Register("Test", typeof(string), typeof(TestUserControl),
new FrameworkPropertyMetadata((string)String.Empty));
public string Test
{
get { return (string)GetValue(TestProperty); }
set { SetValue(TestProperty, value); }
}
public TestUserControl()
{
InitializeComponent();
}
}
}
我基本上最终得到的是两个文本框,一个包含在我的 UserControl 中,另一个没有。
两个文本框都应包含文本“TEST”,但只有未嵌入 UserControl的文本框包含文本。
当我像这样跳过 ViewModel 的绑定时:
<uc:TestUserControl Grid.Row="1" Test="TEST" />
文本显示在 TextBox 中,这表明用户控件正常。
这是调试输出:
System.Windows.Data Warning: 56 : Created BindingExpression (hash=52579650) for Binding (hash=50581426) BindingExpression:Path=Test; DataItem=null;
System.Windows.Data Warning: 58 : Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=52579650): Default mode resolved to TwoWay
System.Windows.Data Warning: 61 : BindingExpression (hash=52579650): Default update trigger resolved to LostFocus
System.Windows.Data Warning: 62 : BindingExpression (hash=52579650): Attach to System.Windows.Controls.TextBox.Text (hash=15537542)
System.Windows.Data Warning: 67 : BindingExpression (hash=52579650): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=52579650): Found data context element: TextBox (hash=15537542) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=52579650): Activate with root item MainWindowViewModel (hash=13189358)
System.Windows.Data Warning: 108 : BindingExpression (hash=52579650): At level 0 - for MainWindowViewModel.Test found accessor RuntimePropertyInfo(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=52579650): Replace item at level 0 with MainWindowViewModel (hash=13189358), using accessor RuntimePropertyInfo(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=52579650): GetValue at level 0 from MainWindowViewModel (hash=13189358) using RuntimePropertyInfo(Test): 'TEST'
System.Windows.Data Warning: 80 : BindingExpression (hash=52579650): TransferValue - got raw value 'TEST'
System.Windows.Data Warning: 89 : BindingExpression (hash=52579650): TransferValue - using final value 'TEST'
System.Windows.Data Warning: 56 : Created BindingExpression (hash=26543418) for Binding (hash=62601592) BindingExpression:Path=Test; DataItem=null;
System.Windows.Data Warning: 58 : Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=26543418): Default mode resolved to TwoWay
System.Windows.Data Warning: 61 : BindingExpression (hash=26543418): Default update trigger resolved to LostFocus
System.Windows.Data Warning: 62 : BindingExpression (hash=26543418): Attach to System.Windows.Controls.TextBox.Text (hash=21868813)
System.Windows.Data Warning: 67 : BindingExpression (hash=26543418): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=26543418): Found data context element: TextBox (hash=21868813) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=26543418): Activate with root item TestUserControl (hash=21522166)
System.Windows.Data Warning: 108 : BindingExpression (hash=26543418): At level 0 - for TestUserControl.Test found accessor DependencyProperty(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=26543418): Replace item at level 0 with TestUserControl (hash=21522166), using accessor DependencyProperty(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=26543418): GetValue at level 0 from TestUserControl (hash=21522166) using DependencyProperty(Test): ''
System.Windows.Data Warning: 80 : BindingExpression (hash=26543418): TransferValue - got raw value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=26543418): TransferValue - using final value ''
System.Windows.Data Warning: 56 : Created BindingExpression (hash=3865173) for Binding (hash=22799085) BindingExpression:Path=Test; DataItem=null;
System.Windows.Data Warning: 58 : Path: 'Test'
System.Windows.Data Warning: 60 : BindingExpression (hash=3865173): Default mode resolved to OneWay
System.Windows.Data Warning: 61 : BindingExpression (hash=3865173): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 62 : BindingExpression (hash=3865173): Attach to MyApp.UserControls.TestUserControl.Test (hash=21522166)
System.Windows.Data Warning: 67 : BindingExpression (hash=3865173): Resolving source
System.Windows.Data Warning: 70 : BindingExpression (hash=3865173): Found data context element: TestUserControl (hash=21522166) (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=3865173): Activate with root item TestUserControl (hash=21522166)
System.Windows.Data Warning: 107 : BindingExpression (hash=3865173): At level 0 using cached accessor for TestUserControl.Test: DependencyProperty(Test)
System.Windows.Data Warning: 104 : BindingExpression (hash=3865173): Replace item at level 0 with TestUserControl (hash=21522166), using accessor DependencyProperty(Test)
System.Windows.Data Warning: 101 : BindingExpression (hash=3865173): GetValue at level 0 from TestUserControl (hash=21522166) using DependencyProperty(Test): ''
System.Windows.Data Warning: 80 : BindingExpression (hash=3865173): TransferValue - got raw value ''
System.Windows.Data Warning: 89 : BindingExpression (hash=3865173): TransferValue - using final value ''
请问这个问题是什么原因造成的,如何解决?
解决方案
不要更改 UserControl DataContext - 您正在中断与 Window DataContext 的连接。而是将文本投标更改为通过 ElementName 引用测试属性。
<UserControl x:Class="MyApp.UserControls.TestUserControl"
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"
xmlns:local="clr-namespace:MyApp.UserControls"
mc:Ignorable="d"
Name="userControl"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<TextBox HorizontalAlignment="Left"
TextWrapping="Wrap"
VerticalAlignment="Top"
Width="120"
Text="{Binding Test, ElementName=userControl, PresentationTraceSources.TraceLevel=High}" />
</Grid>
</UserControl>
请注意,即使没有ElementName=userControl
绑定工作,但它会直接连接到 dataContext - MainWindowViewModel.Test 而不是 TestUserControl.Test 属性。在这种情况下,没有绑定的设置属性 - <uc:TestUserControl Grid.Row="1" Test="TEST" />
- 将不起作用。
还将 TestProperty 更改为双向属性:
public static readonly DependencyProperty TestProperty = DependencyProperty.Register
(
"Test",
typeof(string),
typeof(TestUserControl),
new FrameworkPropertyMetadata(String.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault)
);
推荐阅读
- javascript - Highcharts Gantt (JS) - 删除 x 轴上的日期
- javascript - 导入模块的最佳实践是什么?
- git - Git 在重新排序提交后拒绝推送
- javascript - 我需要使用返回的承诺功能吗?
- c++ - 100位数字的总和
- python - 机器人框架 - 如何使用相同名称的函数,但来自我在关键字部分创建的不同 python 库
- angular - 在 Angular 中从 WebServer 发出响应消息
- javascript - 使用 JavaScript 加载 HTML 文件与文件内容长?
- c# - 不带 Unity 的 UWP 运动控制器输入
- xml - xpath 链接两个属性