Отказаться от полной функциональности аккордеона
Если вы можете жить без полного аккордеона, вы можете легко сделать что-то похожее на то, что вы хотите, используя TabControl
, с альтернативной компоновкой (TabStripPlacement="Left"
).
См. Этот вопрос (так же, как в моих комментариях): Создать боковую панель с вкладками с разделами WPF
Существующая библиотека
Существуют библиотеки управления WPF с аккордеонами:
DIY
Вы можете попробовать использоватьTreeView
для реализации вашего аккордеона тоже.Вам просто нужно несколько хитростей в рукаве, чтобы выполнить это:
Во-первых, вам нужно скрыть кнопки просмотра дерева.Они испортят то, что мы пытаемся достичь.Смотрите этот вопрос - TreeView hide [+] [-] кнопки
Во-вторых, вы хотите убедиться, что для свойства IsExpanded
установлено значение true, если TreeViewItem
или один из егодочерние элементы выбраны, и в противном случае установлено значение false.Вы можете сделать это с IMultiValueConverter
в сочетании с Style
для TreeViewItem
.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<!-- ... -->
<TreeView>
<TreeView.Resources>
<local:SelectedItemToIsChildConverter x:Key="isChildConverter" />
<Style TargetType="{x:Type TreeViewItem}">
<Style.Setters>
<Setter Property="IsExpanded">
<Setter.Value>
<MultiBinding Converter="{StaticResource isChildConverter}">
<Binding Path="SelectedItem"
RelativeSource="{RelativeSource AncestorType={x:Type TreeView}}" />
<Binding RelativeSource="{RelativeSource Self}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</TreeView.Resources>
<!-- Children here, or set ItemsSource property via databinding -->
</TreeView>
Вот код для конвертера, в отдельном файле CS:
public class SelectedItemToIsChildConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
TreeViewItem selectedItem = values.Length > 0 ? values[0] as TreeViewItem : null;
TreeViewItem targetItem = values.Length > 1 ? values[1] as TreeViewItem : null;
if (targetItem == null)
return false;
TreeViewItem currentItem = selectedItem;
while (currentItem != null)
{
if (currentItem == targetItem)
return true;
currentItem = currentItem.Parent as TreeViewItem;
}
return false;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
После этого вам придется стилизовать его, чтобы он выглядел хорошо, и поддерживать анимацию.
Как только все это будет сделано, используйте сетку, чтобы разделить ваш пользовательский интерфейс.Используйте привязку данных для отображения содержимого в основной области пользовательского интерфейса на основе выбранного элемента представления дерева.
Редактировать:
На самом деле представление дерева является плохой базой длябаянЯ немного искал подробности об элементах управления аккордеоном, и оказалось, что они, как правило, имеют только один уровень иерархии.
Учитывая это описание, может быть проще использовать DataGrid
, и взятьПреимущество RowDetails
для расширения вашего аккордеонного вида.
Вот краткое руководство: http://www.wpftutorial.net/DataGrid.html#rowDetails
Просто убедитесь, что большинство функций сетки данных отключены.