WPF Usercontrol设置值为dependencyproperty不起作用

时间:2014-02-20 08:41:31

标签: wpf data-binding dependency-properties assign

使用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'。

有人可以这么向我解释这个吗?

由于

2 个答案:

答案 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}}"