Потеря привязки для radiobutton после того, как я установил свойство вручную в коде - PullRequest
2 голосов
/ 11 сентября 2011

У меня есть список на моем WPF xaml, который содержит два элемента. Ниже приведен шаблон стиля для каждого элемента. Теперь в пользовательском интерфейсе это выглядит как группа переключателей (количество переключателей зависит от количества элементов в моем списке).

<Style x:Key="RadioButtonListBoxItemStyle" TargetType="{x:Type ListBoxItem}" >
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate>
                    <RadioButton FlowDirection="LeftToRight"
                                     Margin="10 15"
                                     Content="{Binding Value}"                                      
                                     GroupName="{Binding DisplayGroupName}"
                                     IsChecked="{Binding IsSelected, Mode=TwoWay}" />
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

Теперь я связываю список (имеющий 2 элемента), используя вышеуказанный шаблон стиля, чтобы получить две радиокнопки. Что происходит, все работает довольно хорошо, то есть когда я меняю выбор переключателя в пользовательском интерфейсе, свойство IsSelected корректно обновляется до true или false, в зависимости от того, включена или выключена моя радиосвязь. Но если я попытаюсь установить список в коде вручную, то с этого момента мое связывание переключателей со списком теряется и ничего не происходит.

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

-Ady.

Ответы [ 2 ]

2 голосов
/ 11 сентября 2011

Это распространенная проблема с переключателями в WPF, и она должна иметь необычный аспект привязки, который немного больше функциональности, чем ошибка.

Конструкция привязки предполагает, что только две вещи, которые изменяют значение целевого свойства привязки, являются: а) действиями в пользовательском интерфейсе и б) изменениями свойства источника. Если вы устанавливаете свойство target привязки в коде - как, вы явно устанавливаете Background для Border, даже если оно имеет привязку - привязка решает, что вы знаете, что вы делать, и что это должно просто убраться с дороги. Так что выключается.

Это довольно разумное дизайнерское решение, по большей части. Это лучше, чем бросить исключение, например. Большую часть времени вы все равно не собираетесь устанавливать IsEnabled в коде; Вы позволите привязке сделать это. Особенно, если вы используете MVVM.

Хорошо, а что будет, если в группе есть радио-кнопки?

Когда вы отмечаете одну кнопку в группе, код WPF, который управляет группами радиокнопок, снимает все остальные кнопки в группе, устанавливая для IsChecked значение false в коде. Привязка отключается сама. К сожалению.

Вот решение: если вы используете переключатели и привязку, не используйте группы. Обработайте логику взаимного исключения в коде модели представления. В вашем случае закодируйте модели представлений так, чтобы только один объект в коллекции мог иметь значение IsSelected true в любой момент времени. (Да, это боль.)

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

0 голосов
/ 11 сентября 2011

вы устанавливаете стиль для класса listboxitem, включая привязки.таким образом, когда вы устанавливаете список из кода позади него, он не содержит элементов списка, он содержит элементы из вашего списка.Итак, стиль не применяется.вам нужно сделать <DataTemplate> для типа элемента в вашем списке - фактически сообщая WPF, как вы хотите, чтобы каждый элемент выглядел.

<DataTemplate TargetType="{x:Type MyCustomClass}" >
   <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <CheckBox IsChecked="{Binding Deleteable, Mode=TwoWay}" />
        <Label Content="{Binding Name}" />
      </StackPanel>
   </DataTemplate>
</DataTemplate>

(это не в моей голове, поэтому xaml может быть не совсем правильным)

...