14
votes

I have an Expander control with its IsExpanded property bound to a bool in the mvvm model. The binding works fine until you dont touch the expander. Once you click the arrow in the expander to expand, the binding stops working. Setting the bool ShowPreview to false in the model doesn't collapse the expander.

<Expander Name="pExpander" 
          IsExpanded="{Binding Path=ShowPreview,Mode=OneWay}"
          Header="Preview">
    <TextBlock Text="{Binding Path=Message, Mode=OneWay}"></TextBlock>    
</Expander>
4
Does your object with property ShowPreview implement the INotifyPropertyChanged interface and raise the event when your property is changed?mattythomas2000
Binding Mode should be TwoWay. As soon as you expand on the expander, the OneWay binding collapses and expansion is framework controlled.apandit
Thanks! TwoWay works. But why can't it work oneway? I am only interested in the model controlling the expansion and collapse based on an external event which sets it to true or false. If the framework expands or collapses the expander I am not interested in that value being set back in the model.netraju
If you're not interested in bringing it back, you can have two properties: one for binding and one for determining expansion. The thing with OneWay binding is that if the framework makes changes to the binded property, the binding collapses (ie. no longer applicable). Try putting a one way binding on a Textbox then letting a user edit it, for example. As soon as the user puts in some new data, even if trigger the binding source the textbox won't update with that value.apandit

4 Answers

7
votes

If you remove Mode=OneWay does that fix the problem?

Upon reading your other CTQ (changes to the GUI do not affect the model), I don't have a good suggestion for how to limit the change being seen by the underlying data. What is the difference in:

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

And

myModel.MyProperty = true; // done by a binding
6
votes

What caught me out here is that IsExpanded is OneWay by default, so

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

doesn't work the way I expected. Only if you add Mode=TwoWay, then it works (i.e. the item starts paying attention to my Expanded property, and updating it), as in

<Style TargetType="TreeViewItem">
    <Setter Property="IsExpanded" Value="{Binding Expanded, Mode=TwoWay}"/>
</Style>
1
votes

With Silverlight I do this:

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

The binding is not lost when you manualy expand/collapse one Expander...

0
votes

Do three things,

Make sure your ViewModel is implementing INotifyPropertyChanged. Your ui wont know about the change if your view model doesnt inform it when the property changes

Change the Mode to TwoWay, you want your view model updated when the expander changes and you want your expander updated when the view model changes

Lastly if the above two don't work use a debug converter to ascertain if your binding is failing. there is an example here of how to do this. This is a technique every wpf developer needs.

I know there was an issue with radio buttons that they would lose their bindings when another button in the group was set, i don't think that is the issue here, however a debug converter will help you figure this out.