【问题标题】:WPF sending value to reusable usercontrolWPF 将值发送到可重用的用户控件
【发布时间】:2018-12-09 18:53:25
【问题描述】:

我认为这是关于 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 属性被成功修改。没有问题。问题是当我在用户控件的宿主窗口中以编程方式修改 IsLocalYes 时,此更改不会传播到用户控件中。那么问题来了,当 IsLocalYes 属性发生变化时,如何修改用户控件的 IsYes 属性?

【问题讨论】:

  • IsLocalYes 是什么以及在哪里?
  • 您是否尝试过更改RadioButtonControlTemplate 而不是创建UserControl?另见docs.microsoft.com/en-us/dotnet/framework/wpf/controls/…
  • @Andy,IsLocalYes 是宿主窗口视图模型的一个属性,其中有许多可重用的用户控件。
  • 三件事:第一,绑定真的解决成功了吗?换句话说,uc:RadioUC 使用的 DataContext 实际上是包含IsLocalYes 属性的视图模型吗?我们无法分辨,因为我们看不到... 其次,IsLocalYes 属性的实现是什么样的?第三,你的依赖属性需要实现一个 callbakc,只要它的值从“外部”发生变化,它就会操纵用户控件。
  • @elgonzo,我不知道如何实现回调。前两点没问题。我将立即编辑问题。你能告诉我如何在用户控件中放置回调吗?

标签: wpf user-controls


【解决方案1】:

与其创建自己的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>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-11
    • 2011-01-27
    • 1970-01-01
    • 2011-01-03
    相关资源
    最近更新 更多