Для объединения нескольких кнопок и расширителей требуется синхронизация всех элементов управления.
Вам нужны все кнопки, чтобы закрыть открытый расширитель, и чтобы открывающий расширитель закрыл открытый расширитель.
Вы можете довольно легко сделать это из кода, назвав элементы управления; Однако для реализации этого
Решение с использованием MVVM (с привязкой) немного сложнее, поскольку свойство Expander IsExpanded не поддерживает двустороннюю привязку.
Ключ заключается в реализации преобразователя, используемого Expander, в его состоянии IsExpanded следующим образом:
IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expConv}}
Каждая команда кнопки устанавливает флаг IsButtonSelected в значение true, которое закрывает открытый Expander.
Поскольку расширители используют конвертер, вы можете использовать метод ConvertBack, чтобы закрыть открытый расширитель из открывающего расширителя.
Я включил код, чтобы помочь вам следовать.
Вот вид с 3 кнопками и 2 модулями расширения:
<Window x:Class="Expander.Views.MainView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:Helpers="clr-namespace:Expander.Converters"
Title="Main Window"
Height="400" Width="800">
<Window.Resources>
<Helpers:ExpanderConverter x:Key="expConv"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Button Grid.Row="0" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 1"/>
<Button Grid.Row="1" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 2"/>
<Expander ExpandDirection="Down"
Grid.Row="2" Grid.Column="0"
IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expanderConv}}"
Header="Details">
<StackPanel Orientation="Horizontal">
<Label Content="Name"/>
<TextBox Width="100" />
</StackPanel>
</Expander>
<Button Grid.Row="3" Grid.Column="0" Command="{Binding Path=ButtonSelected}" Content="Command 3"/>
<Expander ExpandDirection="Down"
Grid.Row="4" Grid.Column="0"
IsExpanded="{Binding Path=IsButtonSelected, Converter={StaticResource expanderConv}}"
Header="Details">
<StackPanel Orientation="Horizontal">
<Label Content="Address"/>
<TextBox Width="100"/>
</StackPanel>
</Expander>
</Grid>
</Window>
Вот конвертер, вызываемый из расширителя:
using System;
using System.Globalization;
using System.Windows.Data;
namespace Expander.Converters
{
[ValueConversion(typeof(object), typeof(bool))]
public sealed class ExpanderConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
bool result = (bool)value;
return !result;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
bool result =(bool)value;
return result;
}
}
}
Вот ViewModel:
Я не включил базовый класс ViewModelBase и код команды, потому что вы пометили MVVM, поэтому я предполагаю, что у вас есть собственная реализация для них.
using System.Windows.Input;
using Expander.Commands;
namespace Expander.ViewModels
{
public class MainViewModel : ViewModelBase
{
public MainViewModel()
{
ButtonSelected = new DelegateCommand<object>(OnButtonSelected, CanButtonSelected);
}
public ICommand ButtonSelected { get; set; }
private void OnButtonSelected(object obj)
{
IsButtonSelected = true;
}
private bool CanButtonSelected(object obj)
{
return true;
}
private bool _isButtonSelected = true;
public bool IsButtonSelected
{
get
{
return _isButtonSelected;
}
set
{
_isButtonSelected = value;
OnPropertyChanged("IsButtonSelected");
}
}
}
}