我正在尝试实现名为ParityTypeSelect
的UserControl,其中包含两个RadioButton - Odd
& Even
,UserControl将有一个名为ParityType
的DependencyProperty,它将用于双向绑定。这个想法很简单 - 如果选择了Odd
,ParityType
应该返回1,如果选择Even
,则ParityType
应该返回0。
这是代码 -
XAML(UserControl):
<StackPanel Orientation="Horizontal">
<RadioButton Name="rdoOdd" Content="Odd" Margin="5" Checked="rdoOdd_CheckedChnaged" Unchecked="rdoOdd_CheckedChnaged" />
<RadioButton Name="rdoEven" Content="Even" Margin="5"/>
</StackPanel>
Code-Behind(UserControl):
public partial class ParityTypeSelect : UserControl
{
//Some Code
static ParityTypeSelect()
{
FrameworkPropertyMetadata parityTypeMetaData =
new FrameworkPropertyMetadata(new PropertyChangedCallback(OnParityTypeChanged),
new CoerceValueCallback(CoerceParityTypeValue));
ParityTypeProperty = DependencyProperty.Register("ParityType", typeof(int?), typeof(ParityTypeSelect),
parityTypeMetaData,
new ValidateValueCallback(ValidateParityTypeValue));
}
public static readonly DependencyProperty ParityTypeProperty;
public int? ParityType
{
get { return (int?)GetValue(ParityTypeProperty); }
set { SetValue(ParityTypeProperty, value); }
}
private static void OnParityTypeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ParityTypeSelect select = (ParityTypeSelect)d;
int? newValue = (int?)e.NewValue;
if (newValue != null && newValue <= 1)
{
if (newValue == 1)
select.rdoOdd.IsChecked = true;
else
select.rdoEven.IsChecked = true;
}
else
return;
}
private void rdoOdd_CheckedChnaged(object sender, RoutedEventArgs e)
{
RadioButton radioButton = (RadioButton)sender;
if (radioButton.IsChecked != null)
{
if (radioButton.IsChecked.Value)
SetValue(ParityTypeProperty, 1);
else
SetValue(ParityTypeProperty, 0);
}
}
//Some more Code
}
XAML(消费者):
<StackPanel>
<aucl:ParityTypeSelect ParityType="{Binding Path=Format.FisrtBitType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
......它正在发挥作用。但事实是,这是我第一次实现DependencyProperty。所以如果我做得对,我有点担心。我是否以正确的方式使用OnParityTypeChanged
方法?是使用rdoOdd_CheckedChnaged
事件处理程序来设置proerty值吗?有没有更好或更合适的方法来完成这整个实现?我一直期待着高质量的编码。因此,感谢任何建议,改进建议,WPF
家伙的评论。
答案 0 :(得分:1)
我试图在评论中写这个,但我会把它作为一个单独的答案。我会绑定属性而不是在后面的代码中执行它。你需要一个转换器,因为int?将需要转换为布尔。为了使转换器尽可能通用,我会使用EqualityConverter
,你可以这样绑定:
<RadioButton Content="Odd" Margin="5" IsChecked="{Binding ParityTypeSelect,Mode=TwoWay,Converter={StaticResource equalityConverter}, ConverterParameter=1}" />
转换器的代码在这里:
public class EqualityConverter : IValueConverter
{
public object TrueValue { get; set; }
public object FalseValue { get; set; }
public EqualityConverter()
{
//default the TrueValue and FalseValue to true and false.
//this way we can easily use the same converter for simple comparison or as an IIF statement
TrueValue = true;
FalseValue = false;
}
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null && parameter == null) return TrueValue;
if (value == null && parameter != null) return FalseValue;
//in some cases we might need to compare an enum value to an integer.
//this will fail unless we specifically convert them
if (value is int && parameter is Enum)
parameter = System.Convert.ToInt32(parameter);
else if (value is Enum && parameter is int)
value = System.Convert.ToInt32(value);
return value.Equals(parameter) ? TrueValue : FalseValue;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value == null && TrueValue == null) return true;
if (value == null && FalseValue == null) return false;
if (value.Equals(TrueValue)) return true;
return false;
}
}
我要说的其他一些事情: - 而不是使用usercontrol,你最好从Control继承(就像标准类一样,没有xaml)。然后,将xaml放入名为Generic.xaml的文件中。涉及的内容很少,因此您需要搜索详细信息 - 您对CoerceParityTypeValue和ValidateParityTypeValue进行了不必要的调用,您可以将其保留。 - 定义依赖道具时只需键入“propdp”(不带引号)和push tab - 通常控件的控件以PART_开头命名,例如PART_OddButton
编辑:这篇文章似乎显示了要点但不完整: http://wpftutorial.net/HowToCreateACustomControl.html
答案 1 :(得分:0)
但有一件事可能会更好,而不是在已更改的事件代码中设置单选按钮的值,您可以将它们绑定在xaml中,如
<RadioButton Name="rdoOdd" Content="Odd" Margin="5" IsChecked="{Binding ParityTypeSelect,Mode=TwoWay,Converter=StaticResource booltoNullIntConverter }" />
booltoNullIntConverter是一个根据您的要求将bool更改为null int的转换器。我希望这会有所帮助。