【问题标题】:Binding to a custom XAML control property won't work绑定到自定义 XAML 控件属性将不起作用
【发布时间】:2016-04-23 16:16:07
【问题描述】:

我正在尝试使用 C# 和 XAML 创建 Windows 10 UWP 应用程序。 在这一点上,我完全被项目模板中的数据绑定所困扰。

所以基本上,我有一个绑定到 XAML 控件的 ViewModel。

我想将数据模型绑定到自定义控件的属性。问题是有些东西有效,有些无效,我真的不明白为什么。

所以这个绑定有效:

  <GridView   ItemsSource="{Binding MediaElementId}" >
       <GridView.ItemTemplate>
           <DataTemplate>
               <TextBlock Text="{Binding}" />
           </DataTemplate>
        </GridView.ItemTemplate>
   </GridView>

但是当我将其他东西放入 TextBlock 时,它就不起作用了。

例如,这些绑定不起作用

<TextBlock  Text="{Binding  Path=.}"/>
 <controls:CustomControl Test="{Binding Path=., UpdateSourceTrigger=PropertyChanged}"  />
 <controls:CustomControl Test="{Binding Path=., RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"/>
 <controls:CustomControl Test="{Binding}"/>

所以,我基本上找到了文档,{Binding} 与 {Binding Path=.} 等价,但在这个例子中,它看起来并不是这样。

您可以自己在一个项目中尝试,我在其中隔离了问题: https://bitbucket.org/MrGreeny/pivottestapp/src/4edee74acfac6dbb4f9f042acaf389cc6fd90a31?at=master

编辑: 该属性是一个非常简单的属性:

    private string test;

    public string Test
    {
        get { return null; }
        set
        {
            Debug.WriteLine(value);
           //What i think should be here is for example textblock.Text = value
        }
    }

【问题讨论】:

  • UWP 应用的 Property-path syntax 文章没有提到我们从 WPF 中知道的 Path=. 语法。但是不知道为什么 &lt;controls:CustomControl Test="{Binding}"/&gt; 不起作用,因为如果 Test 属性,您还没有显示声明。
  • 好吧,我尝试了很多 Test 属性的实现。当前是:private string test;public string Test { get { return null; } set { Debug.WriteLine(value); } }
  • 不要将其作为评论发布,它的格式不正确。改为编辑您的问题。也就是说,Test 必须是一个依赖属性才能成为绑定的目标。
  • 快速查看您的位桶代码,我认为您需要创建一个依赖属性:wpftutorial.net/DependencyProperties.html
  • @CodingGorilla 最好参考Dependency properties overview。这是 UWP,不是 WPF。

标签: c# xaml binding windows-10 uwp


【解决方案1】:

所以,基本上我所要做的就是使用DependencyProperty 而不是普通属性。这是可行的解决方案:

首先是DataTemplate里面的控件:

<GridView ItemsSource="{Binding MediaElementId}" >
   <GridView.ItemTemplate>
      <DataTemplate>
         <local:CustomControl TextBlockContent="{Binding}" />
      </DataTemplate>
   </GridView.ItemTemplate>
 </GridView>

然后在自定义控件xaml.cs文件中:

首先是暴露DependencyProperty的包装器:

public string TextBlockContentProperty
{
    get { return (string)GetValue(TextBlockContentPropertyProperty); }
    set { SetValue(TextBlockContentPropertyProperty, value); }
}

然后是DependencyProperty 本身。

     public static readonly DependencyProperty TextBlockContentPropertyProperty =
        DependencyProperty.Register(
           "TextBlockContentProperty", 
           typeof(string), 
           typeof(CustomControl), 
           new PropertyMetadata(0, new PropertyChangedCallback(OnTextChanged)) );

注意,最后一个参数包含与OnTextChanged 函数的连接,我们可以在其中访问对象实例。以上都是static,我们不能用它们来改变对象的实例。

这是我实现实例特定逻辑的方式。 TextBlockContent 是普通属性,它暴露了TextBlockText 属性,即自定义控件的内容。

    private static void OnTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        CustomControl cc = d as CustomControl;
        string content = (string)e.NewValue;
        cc.TextBlockContent = content;
    }

感谢所有回答我最初问题的人。

【讨论】:

  • 不是在现有的具体属性周围添加依赖属性wrapper,而是使用依赖属性,所以替换 原始属性,因为没有附加值,类上有两个属性公开相同的功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
  • 1970-01-01
  • 2013-03-29
  • 2011-05-11
  • 2018-03-11
相关资源
最近更新 更多