WPF&棱镜:RadioButton选择在多个UserControl上消失

时间:2018-05-25 14:35:00

标签: c# wpf xaml prism

我在几个UserControls中使用Prism的InteractionRequestTrigger来显示使用我自己的窗口内容的通知,例如TestControl包含三个RadioButtons。在TestControl的VM创建时间中,我在第一个单选按钮上设置了选择。

问题是,当显示最后窗口时,单选按钮是 选择它应该是。但之前创建的所有其他窗口都没有任何选择。我发现调用了EnumToBooleanConverter的{​​{1}}函数,并在选择了下一个用户控件的第一个单选按钮时再次取消选择它。等等......你知道为什么吗?怎么解决这个?

以下是重现此问题的简单代码:

主窗口:

ConvertBack

MainViewModel:

  <Window x:Class="WpfApp1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:prism="http://www.codeplex.com/prism"
    xmlns:local="clr-namespace:WpfApp1"
    xmlns:vm="clr-namespace:WpfApp1.ViewModels" Title="MainWindow">
<StackPanel>
    <i:Interaction.Triggers>
        <prism:InteractionRequestTrigger SourceObject="{Binding StretchModeRequest1}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <local:TestControl/>
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>

        <prism:InteractionRequestTrigger SourceObject="{Binding StretchModeRequest2}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <local:TestControl/>
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>

        <prism:InteractionRequestTrigger SourceObject="{Binding StretchModeRequest3}">
            <prism:PopupWindowAction IsModal="True" CenterOverAssociatedObject="True">
                <prism:PopupWindowAction.WindowContent>
                    <local:TestControl/>
                </prism:PopupWindowAction.WindowContent>
            </prism:PopupWindowAction>
        </prism:InteractionRequestTrigger>
    </i:Interaction.Triggers>

    <Button Content="Command 1" Margin="5" Command="{Binding ClickCommand}" CommandParameter="1"/>
    <Button Content="Command 2" Margin="5" Command="{Binding ClickCommand}" CommandParameter="2"/>
    <Button Content="Command 3" Margin="5" Command="{Binding ClickCommand}" CommandParameter="3"/>

</StackPanel>

系统testControl:

public class ViewModel : BindableBase
{
    public InteractionRequest<Confirmation> StretchModeRequest1 { get; private set; }
    public InteractionRequest<Confirmation> StretchModeRequest2 { get; private set; }
    public InteractionRequest<Confirmation> StretchModeRequest3 { get; private set; }

    public ICommand ClickCommand { get; private set; }

    public ViewModel()
    {
        StretchModeRequest1 = new InteractionRequest<Confirmation>();
        StretchModeRequest2 = new InteractionRequest<Confirmation>();
        StretchModeRequest3 = new InteractionRequest<Confirmation>();

        ClickCommand = new DelegateCommand<object>(OnClicked);
    }

    private void OnClicked(object obj)
    {
        int index = Convert.ToInt32(obj);
        var confirmation = new Confirmation() { Content = "Test", Title = string.Format("Bla {0}", index) };
        switch (index)
        {
            case 1: StretchModeRequest1.Raise(confirmation); break;
            case 2: StretchModeRequest2.Raise(confirmation); break;
            case 3: StretchModeRequest3.Raise(confirmation); break;
            default:
                break;
        }
    }
}

TestViewModel:

 <UserControl x:Class="WpfApp1.TestControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:local="clr-namespace:WpfApp1"
         xmlns:vm="clr-namespace:WpfApp1.ViewModels">
<UserControl.Resources>
    <ResourceDictionary>
        <local:EnumToBooleanConverter x:Key="EnumToBooleanConverter"/>
    </ResourceDictionary>
</UserControl.Resources>

<UserControl.DataContext>
    <vm:TestViewModel/>
</UserControl.DataContext>

<StackPanel Margin="3,3,3,0">

    <RadioButton Margin="2" GroupName="Mode" Content="None" IsChecked="{Binding SelectedMode, 
        diag:PresentationTraceSources.TraceLevel=High, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.None}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <RadioButton Margin="2" GroupName="Mode" Content="Limits" IsChecked="{Binding SelectedMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.Limits}, Mode=TwoWay}"/>
    <RadioButton Margin="2" GroupName="Mode" Content="Static" IsChecked="{Binding SelectedMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.Static}, Mode=TwoWay}"/>
</StackPanel>

转换器:

public class TestViewModel : BindableBase
{
    private StretchType _stretchMode;

    public TestViewModel()
    {
        SelectedMode = StretchType.None;
    }

    public StretchType SelectedMode
    {
        get { return _stretchMode; }
        set { SetProperty(ref _stretchMode, value); }
    }
}

1 个答案:

答案 0 :(得分:1)

您应为每个视图使用唯一的GroupName ,. e.g。:

<RadioButton Margin="2" GroupName="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" Content="None" IsChecked="{Binding SelectedMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.None}, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<RadioButton Margin="2" GroupName="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" Content="Limits" IsChecked="{Binding SelectedMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.Limits}, Mode=TwoWay}"/>
<RadioButton Margin="2" GroupName="{Binding RelativeSource={RelativeSource AncestorType=UserControl}}" Content="Static" IsChecked="{Binding SelectedMode, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static vm:StretchType.Static}, Mode=TwoWay}"/>