【发布时间】:2017-01-28 18:02:09
【问题描述】:
我有一个真的简单的UserControl
<UserControl x:Class="Namespace.Views.TabViews.TabViewTemplate"
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="900" d:DesignWidth="880"
d:DataContext="{d:DesignData Type=TabViewTemplate}">
<UserControl.Template>
<ControlTemplate TargetType="UserControl">
<Grid Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderBrush="#FFB31B16" BorderThickness="0,0,0,1" Margin="20" VerticalAlignment="Top">
<TextBlock VerticalAlignment="Bottom" FontSize="20" LineHeight="24" Margin="0,0,0,5" Text="{Binding RelativeSource={RelativeSource AncestorType=UserControl}, Path=Title}"/>
</Border>
<Border Grid.Row="1" Padding="20">
<ContentPresenter ContentSource="Content"/>
</Border>
</Grid>
</ControlTemplate>
</UserControl.Template>
</UserControl>
这是背后的代码
using System;
using System.Windows;
using System.Windows.Markup;
namespace Namespace.Views.TabViews {
/// <summary>
/// Interaction logic for TabViewTemplate.xaml
/// </summary>
[ContentProperty("Content")]
public partial class TabViewTemplate {
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(TabViewTemplate),
new FrameworkPropertyMetadata(
"Sample",
FrameworkPropertyMetadataOptions.AffectsRender,
OnTitleChanged)
);
private static void OnTitleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
var control = d as TabViewTemplate;
if (control != null) control.Title = (string)e.NewValue;
}
public TabViewTemplate() {
InitializeComponent();
}
public static void SetTitle(TabViewTemplate element, string value) {
element.SetValue(TitleProperty, value);
}
public static string GetTitle(TabViewTemplate element) {
return (string) element.GetValue(TitleProperty);
}
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
}
}
我使用这样的代码
<UserControl x:Class="Namespace.Views.TabViews.WelcomeTabView"
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"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
xmlns:tabViews="clr-namespace:Namespace.Views.TabViews"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<tabViews:TabViewTemplate Title="Welcome">
<Grid>
<Border BorderBrush="Coral" BorderThickness="2" Margin="0">
<Image gif:ImageBehavior.AnimatedSource="../../Resources/js_cfg_install_howto.gif"/>
</Border>
</Grid>
</tabViews:TabViewTemplate>
</UserControl>
然而,值“Welcome”通过属性获得set——我通过属性设置器上的断点看到这一点——但是从未调用过get。我使用了各种绑定组合,但都不起作用。通过DependencyProperty 设置 TextBlock 文本的“正确”方法是什么?谢谢!
【问题讨论】:
-
OnTitleChanged被调用了吗?尝试将PresentationTraceSources.TraceLevel=High添加到TextBlock上的Title绑定。这将在“输出”窗格中为您提供 Binding 如何尝试解析源和路径的跟踪信息,这应该会告诉您问题出在哪里。 -
当在 XAML 中设置依赖属性的值时,可能不会调用依赖属性的设置器。原因在 MSDN 上的XAML Loading and Dependency Properties 文章中进行了解释。所以设置断点可能没有任何帮助。
-
也就是说,您的 UserControl 的结构看起来很可疑。通常您只需将元素添加到其 XAML 中的顶级面板,然后通过
Text={Binding Title, RelativeSource={RelativeSource AncestorType=UserControl}}"将元素属性(如 TextBlock.Text)绑定到 UserControl 的依赖项属性(如您的 Title 属性)。 -
此外,您的 OnTitleChanged 方法中的声明
control.Title = (string)e.NewValue;没有意义,因为控件的 Title 属性的值已经是传递给回调的新值。重新设置是多余的,也没用。 -
也不清楚为什么你有静态的
SetTitle和GetTitle方法用于不是附加属性的常规依赖属性。这些方法都没用。