在 XAML 中更改某些用户控件属性不会在 运行 应用程序之前发生
Changing some user control attributes in XAML doesn't take place before running the application
我有一个自定义 UserControl
,它基本上只是一个带有标题和一些内容的奇特容器:
这就是我在 XAML:
中使用它的方式
<local:MDCard Header="Some Title">
<Grid>
...
...
</Grid>
</local:MDCard>
问题是在设计时(在 运行 代码之前)这是我在图形 XAML 编辑器中看到的:
请注意标题未显示。
这是我的 UserControl
:
的源代码
<UserControl x:Class="HealthAndWellBeing.MDCard"
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:local="clr-namespace:HealthAndWellBeing"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
x:Name="self">
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
<Grid>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="1" Opacity="0.2" BlurRadius="2"/>
</Grid.Effect>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="0" Opacity="0.12" BlurRadius="8"/>
</Grid.Effect>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="1" Opacity="0.14"/>
</Grid.Effect>
<Border Background="#FFFAFAFA" CornerRadius="2"/>
</Grid>
</Grid>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="#19000000">
<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header}"/>
</Label>
</Border>
<ContentPresenter Grid.Row="1"/>
</Grid>
</Grid>
</ControlTemplate>
</UserControl.Template>
这是我的 code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace HealthAndWellBeing
{
/// <summary>
/// Interaction logic for MDCard.xaml
/// </summary>
public partial class MDCard : UserControl, INotifyPropertyChanged
{
public MDCard()
{
InitializeComponent();
DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyChange(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(MDCard), new PropertyMetadata("Title"));
}
}
那么为什么当我更改 Button
的文本时可以立即在图形 XAML 编辑器中看到它,但更改我的自定义 [=] 的 Header
15=]只能在运行时间看到?
本质上,将标签的 Binding-Signature 从
更改为
<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header}"/>
</Label>
至
<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"/>
</Label>
应该/可以解决问题。
毕竟你不是要解析 ControlTemplate
的 属性 Header
你要给 UserControl
,而是 UserControl
的后代=14=] class 有一个 DependencyProperty
叫做 Header
。
这就是为什么您应该绑定到 TemplatedParent,即 actual UserControl
后代。
在 CustomControl 的情况下,您使用 compile-time 绑定 TemplateBinding
,因为您正在模板化这个特定的 class.
使用 UserControls
但是您使用 Binding
s,它们在运行时通过 System.Reflection
解析。这就是为什么你应该告诉它寻找一个特定的 parent,如果它不是那个特定 class 的 属性。在这种情况下 TemplatedParent
.
但是可以找到 Binding 与 TemplatedBinding 之间更好的解释 here。
我只能假设 "real" WPF 运行时库将简单地帮助您解决实际的 DependencyProperty - 混合(VS 设计器)不会。
我有一个自定义 UserControl
,它基本上只是一个带有标题和一些内容的奇特容器:
<local:MDCard Header="Some Title">
<Grid>
...
...
</Grid>
</local:MDCard>
问题是在设计时(在 运行 代码之前)这是我在图形 XAML 编辑器中看到的:
请注意标题未显示。
这是我的 UserControl
:
<UserControl x:Class="HealthAndWellBeing.MDCard"
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:local="clr-namespace:HealthAndWellBeing"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="300"
x:Name="self">
<UserControl.Template>
<ControlTemplate TargetType="{x:Type UserControl}">
<Grid>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="1" Opacity="0.2" BlurRadius="2"/>
</Grid.Effect>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="0" Opacity="0.12" BlurRadius="8"/>
</Grid.Effect>
<Grid>
<Grid.Effect>
<DropShadowEffect Direction="270" ShadowDepth="1" Opacity="0.14"/>
</Grid.Effect>
<Border Background="#FFFAFAFA" CornerRadius="2"/>
</Grid>
</Grid>
</Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Border Grid.Row="0" BorderThickness="0,0,0,1" BorderBrush="#19000000">
<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header}"/>
</Label>
</Border>
<ContentPresenter Grid.Row="1"/>
</Grid>
</Grid>
</ControlTemplate>
</UserControl.Template>
这是我的 code-behind:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
namespace HealthAndWellBeing
{
/// <summary>
/// Interaction logic for MDCard.xaml
/// </summary>
public partial class MDCard : UserControl, INotifyPropertyChanged
{
public MDCard()
{
InitializeComponent();
DataContext = this;
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyChange(string PropertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}
public string Header
{
get { return (string)GetValue(HeaderProperty); }
set { SetValue(HeaderProperty, value); }
}
public static readonly DependencyProperty HeaderProperty = DependencyProperty.Register("Header", typeof(string), typeof(MDCard), new PropertyMetadata("Title"));
}
}
那么为什么当我更改 Button
的文本时可以立即在图形 XAML 编辑器中看到它,但更改我的自定义 [=] 的 Header
15=]只能在运行时间看到?
本质上,将标签的 Binding-Signature 从
更改为<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header}"/>
</Label>
至
<Label FontWeight="Bold" Foreground="#FF616161" Margin="10,10,10,10">
<ContentPresenter Content="{Binding Header, RelativeSource={RelativeSource TemplatedParent}}"/>
</Label>
应该/可以解决问题。
毕竟你不是要解析 ControlTemplate
的 属性 Header
你要给 UserControl
,而是 UserControl
的后代=14=] class 有一个 DependencyProperty
叫做 Header
。
这就是为什么您应该绑定到 TemplatedParent,即 actual UserControl
后代。
在 CustomControl 的情况下,您使用 compile-time 绑定 TemplateBinding
,因为您正在模板化这个特定的 class.
使用 UserControls
但是您使用 Binding
s,它们在运行时通过 System.Reflection
解析。这就是为什么你应该告诉它寻找一个特定的 parent,如果它不是那个特定 class 的 属性。在这种情况下 TemplatedParent
.
但是可以找到 Binding 与 TemplatedBinding 之间更好的解释 here。
我只能假设 "real" WPF 运行时库将简单地帮助您解决实际的 DependencyProperty - 混合(VS 设计器)不会。