c#uwp中的双绑定
我有个问题。我为我的应用程序创建了两个控件:底部菜单控件和结果框。ResultBox包含在BottomMenu中,因此顺序如下:Page->BottomMenu->ResultBox。我在ResultBox中创建了一个名为Result of type string的依赖项属性c#uwp中的双绑定,c#,xaml,binding,uwp,C#,Xaml,Binding,Uwp,我有个问题。我为我的应用程序创建了两个控件:底部菜单控件和结果框。ResultBox包含在BottomMenu中,因此顺序如下:Page->BottomMenu->ResultBox。我在ResultBox中创建了一个名为Result of type string的依赖项属性 public ResultBox() { this.InitializeComponent(); this.DataContext = this; } //
public ResultBox()
{
this.InitializeComponent();
this.DataContext = this;
}
/// <summary>
/// Property used to store the result of the calculation
/// </summary>
public static readonly DependencyProperty ResultProperty = DependencyProperty.Register(
"Result",
typeof(string),
typeof(ResultBox),
new PropertyMetadata(null)
);
/// <summary>
/// String holding the text assigned to the Result
/// </summary>
public string Result
{
get => (string)GetValue(ResultProperty);
set => SetValue(ResultProperty, value);
}
public ResultBox()
{
this.InitializeComponent();
this.DataContext=this;
}
///
///用于存储计算结果的属性
///
公共静态只读DependencyProperty结果属性=DependencyProperty.Register(
“结果”,
类型(字符串),
类型(结果框),
新属性元数据(空)
);
///
///保存指定给结果的文本的字符串
///
公共字符串结果
{
get=>(字符串)GetValue(ResultProperty);
set=>SetValue(ResultProperty,value);
}
其约束力如下:
<TextBlock Style="{StaticResource DefaultTextBlockStyle}"
Text="{Binding Result}"/>
然后,我在底部菜单中创建了相同的依赖项属性,这样就可以直接从页面进行设置
public BottomMenu()
{
this.InitializeComponent();
this.DataContext = this;
}
/// <summary>
/// Property used to store the result of the calculation
/// </summary>
public static readonly DependencyProperty ResultProperty = DependencyProperty.Register(
"Result",
typeof(string),
typeof(BottomMenu),
new PropertyMetadata(null)
);
/// <summary>
/// String holding the text assigned to the Result
/// </summary>
public string Result
{
get => (string)GetValue(ResultProperty);
set => SetValue(ResultProperty, value);
}
public-BottomMenu()
{
this.InitializeComponent();
this.DataContext=this;
}
///
///用于存储计算结果的属性
///
公共静态只读DependencyProperty结果属性=DependencyProperty.Register(
“结果”,
类型(字符串),
类型(底部菜单),
新属性元数据(空)
);
///
///保存指定给结果的文本的字符串
///
公共字符串结果
{
get=>(字符串)GetValue(ResultProperty);
set=>SetValue(ResultProperty,value);
}
和约束:
<local:ResultBox Grid.Row="1" Margin="0 0 0 10"
Result="{Binding Result}"
/>
不幸的是,只有当我在ResultBox声明中直接输入文本时,才会显示文本。当我进行双重绑定并将其输入页面时
<local:BottomMenu Grid.Row="2"
Result="13"/>
它不起作用。我正在学习绑定,我想知道我哪里做错了,或者这是否是做这件事的正确方法
编辑:ResultBox中的绑定不应包含源代码,现已修复。您几乎不应该使用
this.DataContext=this
;内部控制。始终在顶层页面定义DataContext
,并让它一路向下流到每个控件
因此,首先删除
this.DataContext = this;
您已正确定义依赖项属性Result
。要将TextBlock
的Text
绑定到它,您可以命名控件并使用ElementName
绑定,或者更有效地使用x:bind
,如下所示
<TextBlock Style="{StaticResource DefaultTextBlockStyle}" Text="{x:Bind Result, Mode=OneWay}"/>
这也一样
<local:ResultBox Grid.Row="1" Margin="0 0 0 10" Result="{x:Bind Result, Mode=OneWay}" />
希望这有帮助。这里,而不是设置
this.DataContext=this
,我们应该使用(this.Content作为FrameworkElement)代码>如下所示:
public BottomMenu()
{
this.InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}
在上面的代码中,我们没有设置用户控件的数据上下文,而是设置用户控件中第一个子控件的数据上下文。在此之后,BottomMenu
中的ResultBox
可以从BottomMenu
继承数据上下文,并且可以正确设置其Result
属性。有关更多信息,请参阅杰瑞·尼克松的博客:
.注意这是可行的,但这不是UWP中推荐的方法。这样设置DataContext
会中断数据流,并会产生副作用。更不用说在性能方面,它比使用x:Bind
更糟糕。如果有兴趣,可以从中查看关于DataContext=this
的讨论。@JustinXL我同意我们不应该在UserControl
上设置DataContext=this
。这就是为什么我们使用(this.Content as FrameworkElement)设置用户控件中第一个子控件的数据上下文代码>。这将解决上述问题中的数据上下文继承问题。这可能不是UWP中的最佳解决方案,但我认为在UserControl内部使用绑定时,这仍然是一种替代方法。这基本上是一样的,对吗?如果将其设置为this
,则会转到this.Content
。这绝对是一个选择,只是不是一个好的选择。通常,即使没有x:Bind
,也应该使用ElementName
绑定来代替此模式:与ElementName
one相比,这个解决方案可能有点棘手,也很难理解。这里的关键点是我们需要UserControl
级别的数据上下文继承,因此我们不应该设置用户控件的数据上下文。但是,在用户控件内部,我们总是关注自定义DP(或UserControl
的一些现有属性),而不是外部的数据上下文,因此我们可以使用第一个子级(通常是容器)的数据上下文来执行绑定。我认为这也是一个出色的解决方案,它比使用ElementName
还不错。
public ResultBox()
{
this.InitializeComponent();
(this.Content as FrameworkElement).DataContext = this;
}