Привязка RadioButton IsChecked к ListBoxItem IsSelected и ListBox IsFocused

Я видел другие вопросы, очень похожие на этот, но почему-то все еще не могу заставить его работать. Вот сценарий.

Что у меня есть. У меня есть ListBox, который отображает список моих моделей представления. Каждая модель представления имеет список дочерних элементов, которые отображаются в другом вложенном списке. Для этого я использую DataTemplate.

Чего я хочу Я хочу, чтобы у дочерних элементов был RadioButton, который выбирается, когда выбран ListBoxItem и когда ListBox находится в фокусе (внутренний ListBox).

В настоящее время часть IsSelected из вышеперечисленного отлично работает, однако, когда я перехожу от одной модели представления к другой (т.е. первый ListBox теряет фокус), переключатель на первом ListBox остается выбранным.

Вот код:

        <Style TargetType="{x:Type ListBox}">
        <Setter Property="ItemContainerStyle">
            <Setter.Value>
                <Style TargetType="{x:Type ListBoxItem}" >
                    <Setter Property="Margin" Value="2" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <RadioButton Focusable="False">
                                    <RadioButton.Style>
                                        <Style TargetType="{x:Type RadioButton}">
                                            <Style.Triggers>
                                                <DataTrigger Binding="{Binding Path=IsFocused, Mode=OneWay, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBox}}}" Value="False">
                                                    <Setter Property="IsChecked" Value="False"/>
                                                </DataTrigger>
                                            </Style.Triggers>
                                        </Style>
                                    </RadioButton.Style>
                                    <RadioButton.IsChecked>
                                        <Binding Path="IsSelected" Mode="TwoWay" RelativeSource="{RelativeSource TemplatedParent}" />
                                    </RadioButton.IsChecked>
                                    <ContentPresenter></ContentPresenter>
                                </RadioButton>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </Setter.Value>
        </Setter>
    </Style>

Я тоже пробовал MultiBinding, но это тоже не помогло. Какие-либо предложения?

ОБНОВЛЕНИЕ Обновите, чтобы включить мою попытку MultiBinding:

<ControlTemplate TargetType="{x:Type ListBoxItem}">
<RadioButton>
<RadioButton.IsChecked>
    <MultiBinding>
        <MultiBinding.Converter>
            <DataExportTool:AllTrueConverter/>
        </MultiBinding.Converter>
        <Binding Path="IsSelected" Mode="TwoWay" RelativeSource="{RelativeSource TemplatedParent}"/>
        <Binding Path="IsFocused" Mode="OneWay" RelativeSource="{RelativeSource TemplatedParent}"/>
    </MultiBinding>
</RadioButton.IsChecked>
<ContentPresenter/>
</RadioButton>
</ControlTemplate>

И конвертер:

public class AllTrueConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return values.Cast<bool>().All(x => x);
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        return Enumerable.Repeat((bool)value, 2).Cast<object>().ToArray();
    }
}

Часть IsSelected отлично работает, т.е. только один элемент в списке имеет радиокнопку, выбранную в любой момент. Однако, когда элемент управления теряет фокус, переключатель выбранного элемента по-прежнему остается выбранным (не то, что я хочу).


person Kelly    schedule 28.08.2009    source источник
comment
Извините, я читал, что вы пробовали MultiBinding ПОСЛЕ ответа. Не могли бы вы объяснить, как вы это сделали?   -  person Carlo    schedule 29.08.2009


Ответы (2)


Вот xaml, который в итоге заработал. Отключение радиокнопки, кажется, является ключевым моментом.

<ControlTemplate TargetType="{x:Type ListBoxItem}">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <RadioButton x:Name="rbIsSelected" IsChecked="False" IsEnabled="False" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="3"  />
        <ContentPresenter Grid.Column="1"/>
    </Grid>
    <ControlTemplate.Triggers>
        <MultiTrigger>
            <MultiTrigger.Conditions>
                <Condition Property="IsSelected" Value="True"/>
                <Condition Property="Selector.IsSelectionActive" Value="True"/>
            </MultiTrigger.Conditions>
            <Setter Property="IsChecked" TargetName="rbIsSelected" Value="True"/>
        </MultiTrigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

Просмотр шаблона по умолчанию очень помог.

person Kelly    schedule 15.09.2009

Используйте MultiBinding вместо обычного Binding, здесь вам также понадобится IMultiValueConverter:

<RadioButton.IsChecked>
    <Binding Path="IsSelected" Mode="TwoWay" RelativeSource="{RelativeSource TemplatedParent}" />
</RadioButton.IsChecked>

Обычно я сам делаю примеры, но эта ссылка должна дать вам хорошая идея в том, как их использовать. В противном случае я приведу упрощенный пример позже.

По сути, вы хотите отправить свойства зависимостей IsFocused и IsSelected в MultiBinding, а затем в MultiValueConverter сказать что-то вроде

return (bool)value[0] && (bool)value[1];

Где значение [0] - IsFocused, а значение 1 - IsSelected или наоборот. наоборот.

Удачи!

person Carlo    schedule 28.08.2009