WPF DependencyProperty 定义和用法

问题描述 投票:0回答:1

我对在 WPF 中创建 DependencyProperties 和扩展其他控件还很陌生。

我扩展了一个 ContentControl,我想将其用作 DialogHeader,我正在遵循过去的做法,但也许我做得不对:

这就是我所拥有的:

DialogHeader.cs

public static class DialogHeader
{
    static DialogHeader()
    {
        AllowDraggingProperty = AllowDraggingPropertyKey.DependencyProperty;
    }

    #region - AllowDragging -

    public static readonly DependencyProperty AllowDraggingProperty;

    private static readonly DependencyPropertyKey AllowDraggingPropertyKey =
        DependencyProperty.RegisterAttachedReadOnly("AllowDragging", typeof(bool), typeof(DialogHeader),
            new PropertyMetadata(false));

    public static bool GetAllowDragging(FrameworkElement element)
    {
        return element is null
               ? throw new ArgumentNullException(nameof(element))
               : (bool)element.GetValue(AllowDraggingProperty);
    }

    public static void SetAllowDragging(FrameworkElement element, bool value)
    {
        if (element is null)
            throw new ArgumentNullException(nameof(element));

        element.SetValue(AllowDraggingProperty, value);
    }

    #endregion - AllowDragging - 
}

ContentControlStyle.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
                    xmlns:b="clr-namespace:WpfToolkit.UX.Controls.Behaviors"
                    xmlns:ux="clr-namespace:WpfToolkit.UX.Controls.Controls">

    <ControlTemplate x:Key="DialogHeader" TargetType="{x:Type ContentControl}">

        <Border x:Name="bdrOuter"
                Height="72"
                Style="{DynamicResource DialogHeader.Border}">

            <ContentControl x:Name="ccDraggableArea"
                            Template="{DynamicResource DraggableArea}">

                <DockPanel LastChildFill="True"
                           Margin="4,0">

                    <Button x:Name="btnClose"
                            DockPanel.Dock="Right"
                            Margin="0,6,0,0"
                            Template="{DynamicResource Close}"
                            VerticalAlignment="Top" />

                    <Image x:Name="imgLogo"
                           DockPanel.Dock="Left"
                           HorizontalAlignment="Left"
                           Margin="0,8,8,4"
                           RenderOptions.BitmapScalingMode="HighQuality"
                           Source="pack://application:,,,/UX.Themes;component/Assets/Branding/Logo.png"
                           Stretch="Uniform" 
                           VerticalAlignment="Center" />

                    <Label x:Name="lblHeading"
                           Content="Dialog Header"
                           DockPanel.Dock="Left"
                           FontFamily="{DynamicResource Inter}"
                           Foreground="{DynamicResource ForegroundBrush}"
                           Template="{DynamicResource DialogHeading}"
                           VerticalAlignment="Center" />

                </DockPanel>

            </ContentControl>

        </Border>

        <ControlTemplate.Triggers>

            <Trigger Property="ux:DialogHeader.AllowDragging" Value="False">
                <Setter TargetName="ccDraggableArea" Property="Visibility" Value="Collapsed" />
            </Trigger>

        </ControlTemplate.Triggers>

    </ControlTemplate>

</ResourceDictionary>

MainWindow.xaml

<TabItem Header="Window Header/Footer" IsSelected="True">

    <Grid Background="Transparent">

        <Grid.RowDefinitions>
            <RowDefinition MinHeight="100" Height="Auto"/>
            <RowDefinition MinHeight="100" Height="Auto"/>
            <RowDefinition MinHeight="100" Height="Auto"/>
            <RowDefinition MinHeight="100" Height="Auto"/>
        </Grid.RowDefinitions>
        
        <ContentControl x:Name="ccHeader"
                        Grid.Row="0"
                        Template="{DynamicResource DialogHeader}"
                        ux:DialogHeader.AllowDragging="False"/>
        
        
        <ContentControl x:Name="ccHeaderCompact"
                        Grid.Row="1"
                        Template="{DynamicResource DialogHeader.Compact}" />
        
        <ContentControl x:Name="ccFooter"
                        Grid.Row="2"
                        Template="{DynamicResource DialogFooter}" />
        
        <ContentControl x:Name="ccFooterCompact"
                        Grid.Row="3"
                        Template="{DynamicResource DialogFooter.Compact}" />
        
    </Grid>
    
</TabItem>

我正在做的是创建我们自己的内部 WPF 控件和模板工具包,以便在我们的几个解决方案中使用。 作为其中的一部分,我正在创建一个显示所有样式和模板的窗口,这就是为什么上面的 MainWindow 有一个选项卡控件。

我目前面临的问题是运行应用程序时,我遇到了这个异常:

InvalidOperationException:“AllowDragging”属性已注册为 只读,没有授权密钥就无法修改。

我认为这是由我的设置引起的,但这在我实现此功能的其他实例中也有效,我以前从未见过 ReadOnly 异常。

c# wpf dependency-properties
1个回答
0
投票

XAML 分配

<ContentControl ... ux:DialogHeader.AllowDragging="False" />

表示您不想创建只读附加属性,因此您不得使用

DependencyProperty.RegisterAttachedReadOnly
。请使用
DependencyProperty.RegisterAttached
来代替。

您的代码应如下所示:

public static class DialogHeader
{
    public static readonly DependencyProperty AllowDraggingProperty =
        DependencyProperty.RegisterAttached(
            "AllowDragging", typeof(bool), typeof(DialogHeader));

    public static bool GetAllowDragging(FrameworkElement element)
    {
        return (bool)element.GetValue(AllowDraggingProperty);
    }

    public static void SetAllowDragging(FrameworkElement element, bool value)
    {
        element.SetValue(AllowDraggingProperty, value);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.