4つのエキスパンダーコントロールがあります。1つのエキスパンダーがエキスパンドされたときに、他のすべてのエキスパンダーを折りたたむ/閉じるにはどうすればよいですか?
7 に答える
次のコードを試してください。
XAML:
<StackPanel Name="StackPanel1">
<StackPanel.Resources>
<local:ExpanderToBooleanConverter x:Key="ExpanderToBooleanConverter" />
</StackPanel.Resources>
<Expander Header="Expander 1"
IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=1}">
<TextBlock>Expander 1</TextBlock>
</Expander>
<Expander Header="Expander 2"
IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=2}">
<TextBlock>Expander 2</TextBlock>
</Expander>
<Expander Header="Expander 3"
IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=3}">
<TextBlock>Expander 3</TextBlock>
</Expander>
<Expander Header="Expander 4"
IsExpanded="{Binding SelectedExpander, Mode=TwoWay, Converter={StaticResource ExpanderToBooleanConverter}, ConverterParameter=4}">
<TextBlock>Expander 4</TextBlock>
</Expander>
</StackPanel>
コンバータ:
public class ExpanderToBooleanConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (value == parameter);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (System.Convert.ToBoolean(value)) return parameter;
return null;
}
}
ViewModel:
public class ExpanderListViewModel
{
public Object SelectedExpander { get; set; }
}
初期化
StackPanel1.DataContext = new ExpanderListViewModel();
説明:
XAMLには、4つのエクスパンダーがあります。それらはすべて、コンテナから。を介してViewModel
(タイプの)を継承します。ExpanderListViewModel
StackPanel
DataContext
それらはすべて、ViewModel
クラスの単一のプロパティにバインドされます。ConverterParameter
そして、バインディングで使用する独自のインデックスを定義しました。SelectedExpander
エキスパンダーを展開すると、そのインデックスがプロパティに保存されます。そして、そのインデックスを使用して、保存されたインデックスが指定されたインデックスと一致する場合、および保存されたインデックスが一致しない場合にConverter
戻ります。true
false
クラスのメソッドにブレークポイントを設定するConvert
と、何が起こっているかがわかります。ConvertBack
Converter
これは私がそれをした方法です:
1)StackPanelを追加し、名前タグ属性を追加する必要があります(これはマスターであるため)。
StackPanel Name = "StackPanel1"
2)必要な数のエキスパンダー(必要に応じて1から100)を追加します。それぞれに次のものが必要です。-
Expanded = "Expander_Expanded"
追加されました(すべてが100%同じ表現であることに注意してください)。
3)他の詳細をそれぞれに一致させる必要はありません(高さの名前などは必要ありません)。
Xaml:
<StackPanel Name="StackPanel1">
<Expander Header="Expander 1" Expanded="Expander_Expanded">
<TextBlock>Expander 1</TextBlock>
</Expander>
<Expander Header="Expander 2" Expanded="Expander_Expanded">
<TextBlock>Expander 2</TextBlock>
</Expander>
<Expander Header="Expander 3" Expanded="Expander_Expanded" >
<TextBlock>Expander 3</TextBlock>
</Expander>
<Expander Header="Expander 4" Expanded="Expander_Expanded" >
<TextBlock>Expander 4</TextBlock>
</Expander>
4)名前付きの「StackPanel1」StackPanelのすべての「Expanders」の開閉を制御するには、以下のコードを1回追加するだけです。
VBコードビハインド:
Private Sub Expander_Expanded(sender As Object, e As RoutedEventArgs)
For Each exp As Expander In StackPanel1.Children
If exp IsNot sender Then
exp.IsExpanded = False
End If
Next
End Sub
5)これで、コンテンツ、ボタン、テキストボックスなどを変更/追加できます。コードを更新せずに、「StackPanel Name」2、「Expander Expanded」の2つを変更する必要はありません。そうしないと、機能しません。
この情報がお役に立てば幸いです。
何が起こっていますか?
1)すべてのパネルは親であり、そのパネルのすべてのコントロールは子です。
2)すべてのコントロールは親パネルの子です。
3)クラスは一度に1つの呼び出しを処理します。
4)クラスは子供を扱います。
6)クラスは次の子供に移動します。
7)すべての子供が尋ねられたら停止します。
したがって、擬似コードは次のようになります。
1)xという名前の子供の話を聞く
2)子供の親リストの各子供に尋ねる
3)子供が電話をかけていない場合
4)子が展開されるのは誤りです
5)その子供に尋ねるのをやめる
6)次の子供に移動し、もう一度尋ねます
7)すべての子供が尋ねられるまで
ロストフォーカスを設定するだけがこれを行う最も簡単な方法のようです。
Xaml:
<Expander LostFocus="CollapseExpander" ExpandDirection="Down" Width="175">
<ListBox Height="265" Margin="0,5,0,10">
</ListBox>
</Expander>
VB:
Private Sub CollapseExpander(ByVal sender As System.Object, ByVal e As System.Windows.RoutedEventArgs)
sender.IsExpanded = False
End Sub
MVVMを使用して、IsExpandedプロパティをビューモデルのブールフラグにバインドします。1つがに更新されたらtrue
、他のすべてをに設定しfalse
ます。
@ wassim-azirarは受け入れられた答えを求めました:
アプリケーションの起動時に「Expander1」を展開するにはどうすればよいですか?
ViewModelに追加しました:
SelectedExpander = "1";
「1」はXAMLの「1」と同じオブジェクトではないため、これは機能しません。そのため、デサイクロンの回答を次のように変更しました。
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return (string)value == (string)parameter;
}
デサイクロンの答えは私にとって非常に役に立ちました-ありがとう。
それで、誰かがそれを必要とするならば、私は私の経験を共有したいと思います。
WPFツールキットのアコーディオンコントロールをお試しください-2010年2月リリース
http://www.dotnetspark.com/kb/1931-accordion-wpf-toolkit-tutorial.aspx
サンプルコード:
<my:Accordion x:Name="accordion1" VerticalAlignment="Top" HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch" SelectionMode="ZeroOrOne">
<my:AccordionItem Header="First Header" Content="First Content"/>
<my:AccordionItem Header="Second Header">
<StackPanel Height="300">
<TextBlock Text="Second Content" /></StackPanel>
</my:AccordionItem>
<my:AccordionItem>
<my:AccordionItem.Header>
<TextBox Text="Third Item" />
</my:AccordionItem.Header>
<StackPanel Height="300">
<TextBlock Text="Third Item" />
</StackPanel>
</my:AccordionItem>
<my:AccordionItem>
<my:AccordionItem.Header>
<TextBlock Text="Fourth Item" />
</my:AccordionItem.Header>
<StackPanel Height="300">
<TextBlock Text="Third Item" />
</StackPanel>
</my:AccordionItem>
</my:Accordion>
私もこれが必要でしたが、すべての答えはIMOの作業が多すぎました。これが私がそれをした方法です:
- StackPanelを追加しました(子の整列は垂直に設定されています)。
- それに3つのエキスパンダーを追加しました。(3が必要)
- エキスパンダーの高さを120pxに設定して、要素を追加します。
- ex1..3と呼ばれる各エキスパンダー。
それぞれに2つのイベントがあります
private void ex1_Collapsed(object sender, RoutedEventArgs e) { ex1.Height = 23.0; } private void ex1_Expanded(object sender, RoutedEventArgs e) { ex1.Height = 120.0; ex2.IsExpanded = false; ex3.IsExpanded = false; }
- window_loadedで折りたたまれた高さを23pxに戻す必要があるすべてのエキスパンダーをリセットします。
そのこと。