WPF 将值发送到可重用的用户控件
WPF sending value to reusable usercontrol
我认为这是 WFP 中级内容的初学者问题。
我有一个用户控件,它使用两个普通按钮充当单选按钮:
(按钮改变颜色以显示当前选择)
<UserControl x:Class="UI.UserControls.RadioUC" Loaded="UserControl_Loaded">
<Stackpanel DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<TextBlock Text="{Binding Path=Title}"/>
<Button x:Name="BtnYes" Content="YES" Click="BtnYes_Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button x:Name="BtnNo" Content="NO" Click="BtnNo_Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Stackpanel>
</UserControl>
代码隐藏由 2 个依赖属性 Title 和 IsYes 组成。
当使用点击事件点击按钮时,IsYes 属性 被修改。
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(RadioUC),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static readonly DependencyProperty IsYesProperty = DependencyProperty.Register("IsYes", typeof(bool), typeof(RadioUC),
new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool IsYes {
get { return (bool)GetValue(IsYesProperty); }
set { SetValue(IsYesProperty, value); }
}
public String Title {
get { return (String)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
private void BtnYes_Click(object sender, RoutedEventArgs e)
{
IsYes = true;
//BtnYes.Background = new SolidColorBrush(Colors.ForestGreen);
//BtnNo.Background = new SolidColorBrush(Colors.Gray);
}
private void BtnNo_Click(object sender, RoutedEventArgs e)
{
IsYes = false;
//BtnNo.Background = new SolidColorBrush(Colors.ForestGreen);
//BtnYes.Background = new SolidColorBrush(Colors.Gray);
}
最后是我的使用方式:
<uc:RadioUC Title="Is it YES" IsYes="{Binding IsLocalYes, Mode=TwoWay}"/>
当按钮被单独点击时,用户控件的IsYes 属性修改成功。没有问题。问题是当我在用户控件的托管 window 中以编程方式修改 IsLocalYes 时,此更改不会传播到用户控件中。所以问题是,当 IsLocalYes 属性 发生变化时,如何修改用户控件的 IsYes 属性?
与其创建自己的 UserControl
,不如使用 ToggleButton
并更改 ControlTemplate
/Style
。
另请阅读此 article
解法:
切换按钮样式:
<Style x:Key="YesNoToggleButtonStyle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Grid x:Name="PART_GRIDYES" Background="Gray" MinWidth="6" MinHeight="6">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">YES</TextBlock>
</Grid>
<Grid x:Name="PART_GRIDNO" Background="Gray" MinWidth="6" MinHeight="6">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">NO</TextBlock>
</Grid>
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="PART_GRIDYES" Property="Background" Value="ForestGreen"></Setter>
</Trigger>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="PART_GRIDNO" Property="Background" Value="ForestGreen"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这样使用:
<ToggleButton Style="{StaticResource YesNoToggleButtonStyle}" IsChecked="{Binding IsLocalYes, Mode=TwoWay}">Is it YES</ToggleButton>
我认为这是 WFP 中级内容的初学者问题。 我有一个用户控件,它使用两个普通按钮充当单选按钮: (按钮改变颜色以显示当前选择)
<UserControl x:Class="UI.UserControls.RadioUC" Loaded="UserControl_Loaded">
<Stackpanel DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}}}">
<TextBlock Text="{Binding Path=Title}"/>
<Button x:Name="BtnYes" Content="YES" Click="BtnYes_Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
<Button x:Name="BtnNo" Content="NO" Click="BtnNo_Click">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding Command}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Button>
</Stackpanel>
</UserControl>
代码隐藏由 2 个依赖属性 Title 和 IsYes 组成。 当使用点击事件点击按钮时,IsYes 属性 被修改。
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register("Title", typeof(string), typeof(RadioUC),
new FrameworkPropertyMetadata(default(string), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public static readonly DependencyProperty IsYesProperty = DependencyProperty.Register("IsYes", typeof(bool), typeof(RadioUC),
new FrameworkPropertyMetadata(default(bool), FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
public bool IsYes {
get { return (bool)GetValue(IsYesProperty); }
set { SetValue(IsYesProperty, value); }
}
public String Title {
get { return (String)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
private void BtnYes_Click(object sender, RoutedEventArgs e)
{
IsYes = true;
//BtnYes.Background = new SolidColorBrush(Colors.ForestGreen);
//BtnNo.Background = new SolidColorBrush(Colors.Gray);
}
private void BtnNo_Click(object sender, RoutedEventArgs e)
{
IsYes = false;
//BtnNo.Background = new SolidColorBrush(Colors.ForestGreen);
//BtnYes.Background = new SolidColorBrush(Colors.Gray);
}
最后是我的使用方式:
<uc:RadioUC Title="Is it YES" IsYes="{Binding IsLocalYes, Mode=TwoWay}"/>
当按钮被单独点击时,用户控件的IsYes 属性修改成功。没有问题。问题是当我在用户控件的托管 window 中以编程方式修改 IsLocalYes 时,此更改不会传播到用户控件中。所以问题是,当 IsLocalYes 属性 发生变化时,如何修改用户控件的 IsYes 属性?
与其创建自己的 UserControl
,不如使用 ToggleButton
并更改 ControlTemplate
/Style
。
另请阅读此 article
解法:
切换按钮样式:
<Style x:Key="YesNoToggleButtonStyle" TargetType="ToggleButton" BasedOn="{StaticResource {x:Type ToggleButton}}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ToggleButton}">
<Grid x:Name="templateRoot" Background="Transparent" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<ContentPresenter x:Name="contentPresenter" Focusable="False" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<Grid x:Name="PART_GRIDYES" Background="Gray" MinWidth="6" MinHeight="6">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">YES</TextBlock>
</Grid>
<Grid x:Name="PART_GRIDNO" Background="Gray" MinWidth="6" MinHeight="6">
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">NO</TextBlock>
</Grid>
</StackPanel>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="true">
<Setter TargetName="PART_GRIDYES" Property="Background" Value="ForestGreen"></Setter>
</Trigger>
<Trigger Property="IsChecked" Value="false">
<Setter TargetName="PART_GRIDNO" Property="Background" Value="ForestGreen"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
这样使用:
<ToggleButton Style="{StaticResource YesNoToggleButtonStyle}" IsChecked="{Binding IsLocalYes, Mode=TwoWay}">Is it YES</ToggleButton>