在运行应用程序之前,不会在XAML中更改某些用户控件属性

时间:2017-12-18 14:41:44

标签: c# wpf xaml user-controls

我有一个自定义UserControl,它基本上只是一个有标题和一些内容的花哨容器:

My Custom <code>UserControl</code> as can be seen when code is running 这就是我在XAML中使用它的方式:

<local:MDCard Header="Some Title">
<Grid>
...
...
</Grid>
</local:MDCard>

问题是在设计时(运行代码之前)这是我在图形XAML编辑器中看到的:

My Custom <code>UserControl</code> as can be seen before running the code

请注意,标题未显示。

这是我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>

这是我的代码隐藏:

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的{​​{1}}只能是在运行时看到了吗?

1 个答案:

答案 0 :(得分:0)

实质上,从

更改标签的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>

应该/可以解决问题。

毕竟,您不是要尝试解析Header的{​​{1}}属性ControlTemplate,而是UserControl类的后代。有UserControl名为DependencyProperty。 这就是你应该绑定到TemplatedParent,即实际 Header后代的原因。

对于CustomControl,您使用编译时绑定UserControl,因为您正在模仿此特定类。

但是TemplateBinding使用UserControls,它们在运行时通过Binding解析。这就是为什么如果它不是特定类的属性,你应该告诉它寻找特定的父类。在这种情况下,System.Reflection

然而,可以找到Binding与TemplatedBinding之间的更好解释here

我只能假设“真正的”WPF运行时库只会帮助您解决实际的DependencyProperty - 混合(VS设计者)不会。