我正在基于 UserControl 类制作自定义 WPF 控件。这是一个简单的复选框,带有两条对角线的矩形,当我缩放整个控件时,它们会正确缩放。这是 XAML:
<UserControl x:Name="Container"
x:Class="MyProject.Controls.VirmanCheckbox"
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:MyProject.Controls"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="50" BorderThickness="1" BorderBrush="Black" Width="50" Height="50" Cursor="Hand" IsTabStop="True" Focusable="True" KeyUp="Grid_KeyUp" GotFocus="Container_GotFocus" LostFocus="Container_LostFocus">
<Grid MouseUp="Grid_MouseUp" Background="#00000000">
<Line x:Name="diagonal1" X1="0" Y1="0" X2="{Binding Width, ElementName=Container}" Y2="{Binding Height, ElementName=Container}" Stroke="{Binding ElementName=Container, Path=BorderBrush}" StrokeThickness="{Binding ElementName=Container, Path=BorderThickness}" Visibility="Hidden"/>
<Line x:Name="diagonal2" X1="0" Y1="{Binding Height, ElementName=Container}" X2="{Binding Width, ElementName=Container}" Y2="0" Stroke="{Binding ElementName=Container, Path=BorderBrush}" StrokeThickness="{Binding ElementName=Container, Path=BorderThickness}" Visibility="Hidden"/>
</Grid>
我将DependencyProperty IsChecked
添加到CustomControl类中。如果 IsChecked
为 true
对角线应该可见。如果 IsChecked
为 false
对角线应隐藏。它看起来像这样:
public partial class CustomCheckbox : UserControl
{
public static readonly DependencyProperty IsCheckedProperty;
static CustomCheckbox()
{
IsCheckedProperty = DependencyProperty.Register(
name: "IsChecked",
propertyType: typeof(Boolean),
ownerType: typeof(VirmanCheckbox),
typeMetadata: new FrameworkPropertyMetadata(
defaultValue: false,
flags: FrameworkPropertyMetadataOptions.AffectsRender
)
);
}
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set
{
var old = (bool)GetValue(IsCheckedProperty);
SetValue(IsCheckedProperty, value);
if (old != value)
{
if (value)
{
diagonal1.Visibility = Visibility.Visible;
diagonal2.Visibility = Visibility.Visible;
}
else
{
diagonal1.Visibility = Visibility.Hidden;
diagonal2.Visibility = Visibility.Hidden;
}
}
}
}
}
当我在项目中使用此控件时,我得到以下 XAML:
<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top"/>
在运行时它工作得很好,但在设计时如果我更改 XAML 中的 IsChecked
属性,我的 CustomCheckbox 将不会以图形方式更新。例如,如果我将 IsChecked
设置为 true
,则不会显示对角线:
<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="True"/>
<Controls:CustomCheckbox HorizontalAlignment="Left" VerticalAlignment="Top" IsChecked="False"/>
这两个控件在设计时在视觉上是相同的。我错过了什么?
最佳答案
引用MSDN :
Because the current WPF implementation of the XAML processor behavior for property setting bypasses the wrappers entirely, you should not put any additional logic into the set definitions of the wrapper for your custom dependency property. If you put such logic in the set definition, then the logic will not be executed when the property is set in XAML rather than in code.
您应该注册一个 PropertyChangedCallback
。
public partial class CustomCheckbox : UserControl
{
public CustomCheckbox()
{
InitializeComponent();
}
#region IsChecked
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register("IsChecked",
typeof(bool), typeof(CustomCheckbox),
new FrameworkPropertyMetadata(
false,
FrameworkPropertyMetadataOptions.AffectsRender,
IsCheckedPropertyChanged));
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
#endregion
#region IsCheckedPropertyChanged
private static void IsCheckedPropertyChanged
(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
if (source is CustomCheckbox)
{
CustomCheckbox control = source as CustomCheckbox;
bool value = (bool)e.NewValue;
if (value)
{
control.diagonal1.Visibility = Visibility.Visible;
control.diagonal2.Visibility = Visibility.Visible;
}
else
{
control.diagonal1.Visibility = Visibility.Hidden;
control.diagonal2.Visibility = Visibility.Hidden;
}
}
}
#endregion
}
顺便说一句,在 WPF 中,您通常会交换常规 CheckBox
的模板来更改其外观。
关于c# - 如何让 WPF UserControl 在设计时更新?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42666702/