Привязка WPF Expander IsExpanded

У меня есть элемент управления Expander со свойством IsExpanded, привязанным к логическому значению в модели mvvm. Привязка работает нормально, пока не трогаешь расширитель. Как только вы нажмете стрелку в расширителе для расширения, привязка перестанет работать. Установка для bool ShowPreview значения false в модели не сворачивает расширитель.

<Expander Name="pExpander" 
          IsExpanded="{Binding Path=ShowPreview,Mode=OneWay}"
          Header="Preview">
    <TextBlock Text="{Binding Path=Message, Mode=OneWay}"></TextBlock>    
</Expander>

person netraju    schedule 01.02.2010    source источник
comment
Ваш объект со свойством ShowPreview реализует интерфейс INotifyPropertyChanged и вызывает событие при изменении вашего свойства?   -  person mattythomas2000    schedule 02.02.2010
comment
Режим привязки должен быть TwoWay. Как только вы расширяете расширитель, привязка OneWay сворачивается, и расширение контролируется платформой.   -  person apandit    schedule 02.02.2010
comment
Спасибо! Двухсторонний работает. Но почему это не может работать в одну сторону? Меня интересует только модель, управляющая расширением и схлопыванием на основе внешнего события, которое устанавливает для нее значение true или false. Если фреймворк расширяет или сворачивает расширитель, я не заинтересован в том, чтобы это значение возвращалось в модель.   -  person netraju    schedule 02.02.2010
comment
Если вы не заинтересованы в его возвращении, у вас может быть два свойства: одно для привязки и одно для определения расширения. Дело в том, что привязка OneWay заключается в том, что если фреймворк вносит изменения в свойство привязки, привязка рушится (то есть больше не применяется). Попробуйте установить одностороннюю привязку к текстовому полю, а затем, например, позволить пользователю редактировать его. Как только пользователь вводит новые данные, даже если активировать источник привязки, текстовое поле не будет обновляться с этим значением.   -  person apandit    schedule 03.02.2010


Ответы (4)


Если вы удалите Mode=OneWay, это решит проблему?

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

myModel.MyProperty = true; // in *your* code behind

И

myModel.MyProperty = true; // done by a binding
person user7116    schedule 01.02.2010

Что меня здесь зацепило, так это то, что IsExpanded по умолчанию равно OneWay, поэтому

<Style TargetType="TreeViewItem">
    <Setter Property="IsExpanded" Value="{Binding Expanded}"/>
</Style>

не работает так, как я ожидал. Только если добавить Mode=TwoWay, то работает (т.е. элемент начинает обращать внимание на мое свойство Expanded и обновлять его), как в

<Style TargetType="TreeViewItem">
    <Setter Property="IsExpanded" Value="{Binding Expanded, Mode=TwoWay}"/>
</Style>
person imekon    schedule 21.05.2010

С Silverlight я делаю это:

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"

<Expander Name="pExpander" IsExpanded="True" Header="Preview">
    <i:Interaction.Triggers>
        <ei:PropertyChangedTrigger Binding="{Binding ShowPreview, Mode=OneWay}">
            <ei:ChangePropertyAction PropertyName="IsExpanded" Value="{Binding ShowPreview, Mode=OneWay}"/>
        </ei:PropertyChangedTrigger>
    </i:Interaction.Triggers>
    <TextBlock Text="{Binding Path=Message, Mode=OneWay}"></TextBlock>    
</Expander>
<Expander Name="pExpander1" IsExpanded="True" Header="Preview 1">
    <i:Interaction.Triggers>
        <ei:PropertyChangedTrigger Binding="{Binding ShowPreview, Mode=OneWay}">
            <ei:ChangePropertyAction PropertyName="IsExpanded" Value="{Binding ShowPreview, Mode=OneWay}"/>
        </ei:PropertyChangedTrigger>
    </i:Interaction.Triggers>
    <TextBlock Text="{Binding Path=Message1, Mode=OneWay}"></TextBlock>    
</Expander>
//...

Привязка не теряется при ручном развертывании/сворачивании одного Expander...

person Tonio    schedule 30.05.2012
comment
Единственное, что мне пришлось изменить для wpf, это параметры свойства измененного триггера и значения Binding Path=ShowPreview. В остальном, это было идеально для меня, спасибо. - person Jake Gaston; 30.04.2014

Сделай три дела,

Убедитесь, что ваш ViewModel реализует INotifyPropertyChanged. Ваш пользовательский интерфейс не узнает об изменении, если ваша модель представления не сообщит об этом при изменении свойства.

Измените режим на TwoWay, вы хотите, чтобы ваша модель представления обновлялась при изменении расширителя, и вы хотите, чтобы ваш расширитель обновлялся при изменении модели представления.

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

Я знаю, что была проблема с переключателями, из-за которой они теряли свои привязки, когда была установлена ​​​​другая кнопка в группе, я не думаю, что это проблема, однако преобразователь отладки поможет вам понять это.

person Aran Mulholland    schedule 01.02.2010
comment
Спасибо за ответы. Да, модель реализует INotifyPropertyChanged. Привязка работает нормально, пока не трогаешь расширитель. Как только вы щелкнете мышью по расширителю, чтобы развернуться, привязка больше не работает. В отладке вы можете видеть, что для IsExpanded устанавливается значение true или false. Но визуально расширитель остается расширенным. - person netraju; 02.02.2010
comment
если вы включите преобразователь отладки, будет ли преобразователь отладки срабатывать каждый раз, когда вы меняете свернутое состояние? - person Aran Mulholland; 03.02.2010