我对在 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 异常。
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);
}
}