使用usercontrols和数据绑定时,有一个问题困扰我。 我想知道为什么这不起作用,以及我如何使它工作。
我创建了一个最小的例子(我没有费心去创建视图模型):
首先,有一个包含文本框和按钮的用户控件。
<UserControl x:Class="DatabindingProblem.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="23" d:DesignWidth="300">
<StackPanel Orientation="Horizontal">
<TextBox Text="{Binding Path}" Width="250"></TextBox>
<Button Click="Button_Click" Width="50">click</Button>
</StackPanel>
</UserControl>
后面的代码(一个dependencyproperty“Path”):
namespace DatabindingProblem
{
public partial class UserControl1 : UserControl
{
public UserControl1()
{
InitializeComponent();
}
public string Path
{
get { return (string)GetValue(PathProperty); }
set { SetValue(PathProperty, value); }
}
public static readonly DependencyProperty PathProperty =
DependencyProperty.Register("Path", typeof(string), typeof(UserControl1), new PropertyMetadata(""));
private void Button_Click(object sender, RoutedEventArgs e)
{
Path = "test";
}
}
}
窗口:
<Window x:Class="DatabindingProblem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DatabindingProblem"
Title="MainWindow" Height="350" Width="525">
<Grid>
<local:UserControl1 Height="23" Path="{Binding FilePath}" />
</Grid>
</Window>
windows code-behind(依赖属性FilePath):
namespace DatabindingProblem
{
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public string FilePath
{
get { return (string)GetValue(FilePathProperty); }
set { SetValue(FilePathProperty, value); }
}
public static readonly DependencyProperty FilePathProperty =
DependencyProperty.Register("FilePath", typeof(string), typeof(MainWindow), new PropertyMetadata(""));
}
}
我想知道为什么'test'在文本框中不可见,并且在点击按钮后不会传播到窗口中的'FilePath'。
有人可以这么向我解释这个吗?
由于
答案 0 :(得分:0)
通过默认绑定引擎将在其DataContext 中搜索属性,但由于您没有向UserControl和Window提供任何DataContext,因此绑定会以静默方式失败,您可以在Visual的输出窗口中看到工作室。
您可以使用RelativeSource标记扩展来解决绑定问题。
<强>用户控件:强>
<TextBox Text="{Binding Path,RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=UserControl}}"
Width="250"/>
<强>窗口强>
<local:SampleUserControl Path="{Binding FilePath, Mode=TwoWay,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Window}}"/>
此外,您必须将Mode
设置为TwoWay
,以便任何更改都会从源传播到目标,反之亦然。自定义DP的默认值是OneWay。
但是,您可以在自定义DP Path
中指定它,默认情况下通过在路径DP上设置FrameworkPropertyMetadataOptions.BindsTwoWayByDefault
来绑定TwoWay。这样您就不必在XAML绑定上显式设置绑定模式。
public static readonly DependencyProperty PathProperty =
DependencyProperty.Register("Path", typeof(string), typeof(UserControl1),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
答案 1 :(得分:0)
UserControl1
没有DataContext
设置,因此绑定失败。
当您在代码中使用DP时,将DataContext
设置为RelativeSource Self
将解决此问题。
DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"