【问题标题】:WPF Usercontrol setting value to dependencyproperty does not workWPF Usercontrol 将值设置为依赖属性不起作用
【发布时间】:2014-02-20 08:41:31
【问题描述】:

在使用用户控件和数据绑定时有一个问题困扰着我。 我想知道为什么这不起作用,以及如何使它起作用。

我创建了一个最小的示例(我没有费心创建视图模型):

首先,有一个包含文本框和按钮的用户控件。

<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>

后面的代码(一个依赖属性“路径”):

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 代码隐藏(依赖属性 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(""));
}
}

我想知道为什么“测试”在文本框中不可见,并且在单击按钮后不会传播到窗口中的“文件路径”。

谁能给我解释一下?

谢谢

【问题讨论】:

    标签: wpf data-binding dependency-properties assign


    【解决方案1】:

    默认绑定引擎会在其 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 中指定它以默认绑定 TwoWay,方法是在路径 DP 上设置 FrameworkPropertyMetadataOptions.BindsTwoWayByDefault。这样您就不必在 XAML 绑定上显式设置绑定模式。

    public static readonly DependencyProperty PathProperty =
            DependencyProperty.Register("Path", typeof(string), typeof(UserControl1),
                              new FrameworkPropertyMetadata(string.Empty, 
                             FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    

    【讨论】:

    • 谢谢。我确实在自己的代码中包含了正确的数据上下文,但在上面的简化问题中忘记了它们。看起来是你提到的单向默认导致了我的问题。
    【解决方案2】:

    UserControl1 没有设置DataContext,因此绑定失败。

    当您在代码后面使用 DP 时,将 DataContext 设置为 RelativeSource Self 将解决此问题。

    DataContext="{Binding Mode=OneWay, RelativeSource={RelativeSource Self}}"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-08-31
      • 2011-08-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多