こういうシチュで、右のToggleButton (x:Name = "toggle")押したらー
こうなってほしくって、
こういう中途半端に開いてるやつもー
がばっっと開いてー
こういう中途半端に開いてるやつもー
ガッっっと閉じたいとき
とりあえずExpanderを作りたいので、サンプルデータセットを作って、
てきとーにBindingして、ItemTemplateを書きます。
こんなかんじ。
で、ExpanderのIsExpandedプロパティをtoggleのIsCheckedにBinding
<Expander x:Name="expander" Header="Expander" IsExpanded="{Binding IsChecked, ElementName=toggle, Mode=OneWay}"/>
するとー。
toggleをぽちぽちする分にはいいかんじに、動きます。
が、一度でもExpanderをクリックして開閉したものは、toggleをクリックしても反応しなくなります。
ちなみに、縦に並べているToggleButtonは想定した動きをします。
今回はWPFで作成したので、SnoopでクリックしたExpanderとクリックしてないExpanderを見比べてみます。
触ったExpander
触ってないExpander
Expanderの内部の処理で、Bindingがふっとばされているのがわかります。
なるほど、OneWayだとふっとぶ。。
次にTwoWayを試してみます。
<Expander x:Name="expander" Header="Expander" IsExpanded="{Binding IsChecked, ElementName=toggle, Mode=TwoWay}"/>
予想どおり、どっか開いたら全部開くし、どっか閉じたら全部閉じるし、だめなかんじ。
でも、Bindingはふっとばない。
ここで本題、設定はTwoWayだけど、OneWayみたいにすればいいじゃない。
ということでコンバータを書きます。こんなかんじ。
public class NonBindingConverter :IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return Binding.DoNothing; } }
ぱっと見、なにもしないコンバータですが、こんなふうにつかいます。
<Expander x:Name="expander" Header="Expander" IsExpanded="{Binding IsChecked, Converter={StaticResource NonBindingConverter}, ElementName=toggle, Mode=TwoWay}">
すると、toggleのIsCheckが変化したら、Expanderにそのまま反映しますが、
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { return value; }
ExpanderのIsExpandedはtoggleのIsCheckedに反映しません。
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return Binding.DoNothing; }
なので、振る舞いはOneWayだけど、設定はTwoWayになります。
TwoWayだからBinding式は飛ばないし、挙動はOneWayなのでExpanderを個別に触ってもtoggleで開いたり閉じたりできます。
あれげコンバータに見えるけど、めでたしめでたし。