WPF & Prism: выбор RadioButton исчезает на нескольких пользовательских элементах управления - PullRequest
0 голосов
/ 25 мая 2018

Я использую Prism InteractionRequestTrigger в нескольких пользовательских элементах управления для отображения уведомления с использованием моего собственного содержимого окна, например, TestControl, содержащего три RadioButtons.Во время создания виртуальной машины TestControl я установил выбор на 1-й радиокнопке.

Проблема в том, что при отображении окна last переключатель выбирается так, как и должно быть.Но все другие созданные ранее окна не имеют выбора.Я понял, что моя EnumToBooleanConverter функция ConvertBack вызывается и снова отменяет ее выбор, когда была выбрана первая радиокнопка следующего пользовательского элемента управления.И так далее ... Знаете почему?Как это решить?

Вот простой код для воспроизведения этой проблемы:

MainWindow:

  <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>

MainViewModel:

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;
        }
    }
}

TestControl:

 <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>

TestViewModel:

public class TestViewModel : BindableBase
{
    private StretchType _stretchMode;

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

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

Конвертер:

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return ((bool)value) ? parameter : Binding.DoNothing;
    }
}

1 Ответ

0 голосов
/ 25 мая 2018

Вы должны использовать уникальный GroupName для каждого представления, например:

<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}"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...