Skip to content

Контекстные меню

Контекстные меню

Контролы TreeList и TreeView поддерживают встроенные контекстные меню, вызываемые, когда пользователь щелкает правой кнопкой мыши по контролам. Вы можете настроить эти меню таким образом, чтобы предоставлять пользователям пользовательские контекстно-зависимые команды.

Встроенное контекстное меню заголовка столбца (TreeList)

Когда пользователь щелкает правой кнопкой мыши заголовок столбца TreeList, контрол отображает встроенное меню заголовка столбца. Он содержит команды, которые позволяют пользователю изменять свойства сортировки для выбранного столбца.

treelist-columnheadermenu

Используйте свойство TreeListControl.ColumnMenu, чтобы настроить это меню. Вы можете назначить объект Eremex.AvaloniaUI.Controls.Bars.PopupMenu свойству TreeListControl.ColumnMenu, чтобы заменить меню по умолчанию.

Чтобы настроить существующее меню заголовка столбца (добавить или удалить элементы по умолчанию), откройте меню после его инициализации (например, в обработчике событий Initialized вашего TreeList), а затем измените меню.

Контекст данных

Свойство DataContext заголовочного меню столбца и его элементов (объектов ToolbarButtonItem) определяет объект TreeListColumn, для которого было вызвано меню.

Пример - Как заменить дефолтное меню заголовка столбца на "Меню заголовка столбца по умолчанию"

Следующий код создает пользовательское меню заголовка столбца, содержащее элемент меню Clear Column Data. Код привязывает элемент меню к команде ClearColumnDataCommand, определенной в ViewModel.

treelist-contextmenus-columnmenu-replace-example

Обратите внимание на инициализацию свойств Command и CommandParameter для элемента меню в приведенном ниже коде. Выражение CommandParameter="{Binding FieldName}" определяет привязку к свойству FieldName элемента меню DataContext (TreeListColumn.FieldName).

DataContext в TreeListColumn соответствует DataContext в Tree List (объект ViewModel в этом примере). Это позволяет вам получить доступ к модели представления и ее команде ClearColumnDataCommand, используя выражение: Command="{Binding DataContext.ClearColumnDataCommand}".

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
xmlns:mxb="https://schemas.eremexcontrols.net/avalonia/bars"

<mxtl:TreeListControl Name="treeList1"
                    >
    <mxtl:TreeListControl.ColumnMenu>
        <mxb:PopupMenu>
            <mxb:ToolbarButtonItem
                Header="Clear Column Data"
                Command="{Binding DataContext.ClearColumnDataCommand}"
                CommandParameter="{Binding FieldName}">
            </mxb:ToolbarButtonItem>
        </mxb:PopupMenu>
    </mxtl:TreeListControl.ColumnMenu>
</mxtl:TreeListControl>
public MainView()
{
    DataContext = new ViewModel();
}

public partial class ViewModel : ObservableObject
{
    [RelayCommand]
    void ClearColumnData(string fieldName)
    {
        //...
    }
}

Пример - Как изменить существующее меню заголовка столбца

Следующий пример добавляет пользовательскую команду в дефолтное меню заголовка столбца.

В примере обрабатывается событие TreeListControl.Initialized для доступа к дефолтному меню заголовка столбца после его инициализации и добавляется команда Refresh Data в меню.

treelist-contextmenus-columnmenu-customize-example

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
xmlns:mxb="https://schemas.eremexcontrols.net/avalonia/bars"

<mxtl:TreeListControl Name="treeList1"
                      Initialized="OnInitialized"
                    >
using Eremex.AvaloniaUI.Controls.Bars;
using Eremex.AvaloniaUI.Controls.TreeList;

private void OnInitialized(object sender, System.EventArgs e)
{
    ToolbarButtonItem btn1 = new ToolbarButtonItem();
    btn1.Header = "Refresh Data";
    btn1.ShowSeparator = true;
    btn1.Command = new RelayCommand<TreeListControl>(UpdateTreeList);
    btn1.CommandParameter = treeList1;
    treeList1.ColumnMenu.Items.Add(btn1);
}

[RelayCommand]
void UpdateTreeList(TreeListControl treeList)
{
    //...
}

Меню ячеек строк (TreeList и TreeView)

Контролы TreeList и TreeView поддерживают встроенное контекстное меню для ячеек строк (смотрите свойство TreeListControlBase.RowCellMenu). Это меню изначально пусто и, следовательно, скрыто. Чтобы отобразить меню ячейки строки, заполните его элементами в XAML или в коде.

Контекст данных

DataContext меню ячейки строки и его элементов содержит объект CellData, который позволяет вам получать доступ к информации, зависящей от контекста:

  • CellData.DataControl — Возвращает контрол-контейнер (TreeListControl), для которого вызывается меню.
  • CellData.Row — Возвращает нижележащий объект данных щелкнутого узла.

Пример - Как отобразить одинаковые команды контекстного меню для всех строк

В следующем примере команда "Delete Row" добавляется в меню ячейки строки (TreeListControlBase.RowCellMenu) для всех строк.

treelist-contextmenus-rowmenu-deleterow-example

Приведенный ниже код XAML присваивает свойству TreeListControlBase.RowCellMenu всплывающее меню. Всплывающее меню содержит один элемент (ToolbarButtonItem), привязанный к команде DeleteRowCommand, определенной в модели представления (DataContext Tree List).

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
xmlns:mxb="https://schemas.eremexcontrols.net/avalonia/bars"

<mxtl:TreeListControl Name="treeList1"
                    AutoGenerateColumns="True"
                    ItemsSource="{Binding Departments}"
                    ChildrenFieldName="Children"
                    HasChildrenFieldName="HasChildren"
                    >
    <mxtl:TreeListControl.RowCellMenu>
        <mxb:PopupMenu>
            <mxb:PopupMenu.Items>
                <mxb:ToolbarButtonItem Header="Delete Row"
                 Command="{Binding DataControl.DataContext.DeleteRowCommand}"
                 CommandParameter="{Binding Row}">
                </mxb:ToolbarButtonItem>
            </mxb:PopupMenu.Items>
        </mxb:PopupMenu>
    </mxtl:TreeListControl.RowCellMenu>
</mxtl:TreeListControl>
public partial class MainView : UserControl
{
    MainViewModel viewModel = new MainViewModel();

    public MainView()
    {
        DataContext = viewModel;

        Department depOperations = new Department() 
        { 
            Name = "Operations", Phone = "1110", IsRoot = true 
        };
        Department depManufacturing = new Department() 
        { 
            Name = "Manufacturing", Phone = "1111" 
        };
        Department depQuality = new Department() 
        { 
            Name = "Quality", Phone = "1112" 
        };
        depOperations.Children.Add(depManufacturing);
        depOperations.Children.Add(depQuality);

        Department depMarketing = new Department() 
        { 
            Name = "Marketing", Phone = "3120", IsRoot = true 
        };
        Department depSales = new Department() 
        { 
            Name = "Sales", Phone = "3121" 
        };
        Department depCRM = new Department() 
        { 
            Name = "CRM", Phone = "3122" 
        };
        depMarketing.Children.Add(depSales);
        depMarketing.Children.Add(depCRM);

        Department depAccountsAndFinance = new Department() 
        { 
            Name = "Accounts & Finance", Phone = "5780", IsRoot = true 
        };
        Department depAccounts = new Department() 
        { 
            Name = "Sales", Phone = "5781" 
        };
        Department depFinance = new Department() 
        { 
            Name = "Finance", Phone = "5782" 
        };
        depAccountsAndFinance.Children.Add(depAccounts);
        depAccountsAndFinance.Children.Add(depFinance);

        Department depHumanResources = new Department() 
        { 
            Name = "Human Resources", Phone = "7370", IsRoot = true 
        };
        Department depHR = new Department() 
        { 
            Name = "HR", Phone = "7370" 
        };
        depHumanResources.Children.Add(depHR);

        viewModel.Departments.Add(depOperations);
        viewModel.Departments.Add(depMarketing);
        viewModel.Departments.Add(depAccountsAndFinance);
        viewModel.Departments.Add(depHumanResources);

        InitializeComponent();
    }
}

public partial class MainViewModel : ViewModelBase
{
    public MainViewModel() { }

    public ObservableCollection<Department> Departments { get; } = new();

    [RelayCommand]
    void DeleteRow(Department row)
    {
        DeleteRowRecursively(Departments, row);
    }

    bool DeleteRowRecursively(ObservableCollection<Department> departments, Department row)
    {
        foreach (Department dep in departments)
        {
            if (dep == row)
            {
                departments.Remove(row);
                return true;
            }
            if (DeleteRowRecursively(dep.Children, row))
                break;
        }
        return false;
    }
}

public partial class Department : ObservableObject
{
    [ObservableProperty]
    public string name = "";

    [ObservableProperty]
    public string phone = "0";

    [Browsable(false)]
    public bool IsRoot { get; set; } = false;

    public ObservableCollection<Department> Children { get; } = new();

    public bool HasChildren { get { return Children.Count > 0; } }

    public void AddDepartment(Department department)
    {
        Children.Add(department);
        if (Children.Count == 1)
            OnPropertyChanged(nameof(HasChildren));
    }
}

Пример - Как отобразить разные команды контекстного меню для разных строк

Следующий пример инициализирует контекстное меню для строк (TreeListControlBase.RowCellMenu) и отображает различные элементы меню для корневых и вложенных строк.

В корневом контекстном меню отображается команда "Add Child Dep", в то время как в контекстном меню для вложенных строк отображается команда "Delete Row".

treelist-contextmenus-rowcellmenu-different-example

Код XAML определяет контекстное меню (объект PopupMenu) с помощью команд "Add Child Dep" и "Delete Row". Команда "Add Child Dep" отображается для корневых узлов. Команда "Delete Row" отображается для вложенных узлов. Доступ к этим командам управляется динамически с помощью свойства IsRoot бизнес-объекта.

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"
xmlns:mxe="https://schemas.eremexcontrols.net/avalonia/editors"
xmlns:mxb="https://schemas.eremexcontrols.net/avalonia/bars"

<mxtl:TreeListControl Name="treeList1"
                        AutoGenerateColumns="True"
                        ItemsSource="{Binding Departments}"
                        ChildrenFieldName="Children"
                        HasChildrenFieldName="HasChildren"
                    >
    <mxtl:TreeListControl.RowCellMenu>
        <mxb:PopupMenu>
            <mxb:PopupMenu.Items>
                <mxb:ToolbarButtonItem
                    Header="Add Child Dep"
                    Command="{Binding DataControl.DataContext.AddChildRowCommand}"
                    CommandParameter="{Binding Row}"
                    Glyph="/Assets/add.png"
                    IsVisible="{Binding Row.IsRoot}">
                </mxb:ToolbarButtonItem>
                <mxb:ToolbarButtonItem
                    Header="Delete Row"
                    Command="{Binding DataControl.DataContext.DeleteRowCommand}"
                    CommandParameter="{Binding Row}"
                    Glyph="/Assets/delete.png"
                    IsVisible="{Binding !Row.IsRoot}">
                </mxb:ToolbarButtonItem>
            </mxb:PopupMenu.Items>
        </mxb:PopupMenu>
    </mxtl:TreeListControl.RowCellMenu>
</mxtl:TreeListControl>
public partial class MainView : UserControl
{
    MainViewModel viewModel = new MainViewModel();

    public MainView()
    {
        DataContext = viewModel;

        Department depOperations = new Department() 
        { 
            Name = "Operations", Phone = "1110", IsRoot = true 
        };
        Department depManufacturing = new Department() 
        { 
            Name = "Manufacturing", Phone = "1111" 
        };
        Department depQuality = new Department() 
        { 
            Name = "Quality", Phone = "1112" 
        };
        depOperations.Children.Add(depManufacturing);
        depOperations.Children.Add(depQuality);

        Department depMarketing = new Department() 
        { 
            Name = "Marketing", Phone = "3120", IsRoot = true 
        };
        Department depSales = new Department() 
        { 
            Name = "Sales", Phone = "3121" 
        };
        Department depCRM = new Department() 
        { 
            Name = "CRM", Phone = "3122" 
        };
        depMarketing.Children.Add(depSales);
        depMarketing.Children.Add(depCRM);

        Department depAccountsAndFinance = new Department() 
        { 
            Name = "Accounts & Finance", Phone = "5780", IsRoot = true 
        };
        Department depAccounts = new Department() 
        { 
            Name = "Sales", Phone = "5781" 
        };
        Department depFinance = new Department() 
        { 
            Name = "Finance", Phone = "5782" 
        };
        depAccountsAndFinance.Children.Add(depAccounts);
        depAccountsAndFinance.Children.Add(depFinance);

        Department depHumanResources = new Department() 
        { 
            Name = "Human Resources", Phone = "7370", IsRoot = true 
        };
        Department depHR = new Department() 
        { 
            Name = "HR", Phone = "7370" 
        };
        depHumanResources.Children.Add(depHR);

        viewModel.Departments.Add(depOperations);
        viewModel.Departments.Add(depMarketing);
        viewModel.Departments.Add(depAccountsAndFinance);
        viewModel.Departments.Add(depHumanResources);

        InitializeComponent();
    }
}

public partial class MainViewModel : ViewModelBase
{
    public MainViewModel() { }

    public ObservableCollection<Department> Departments { get; } = new();

    [RelayCommand]
    void AddChildRow(Department parentRow)
    {
        parentRow.AddDepartment(new Department() 
        { 
            Name = "New dep", Phone = "0000" 
        });
    }

    [RelayCommand]
    void DeleteRow(Department row)
    {
        DeleteRowRecursively(Departments, row);
    }

    bool DeleteRowRecursively(ObservableCollection<Department> departments, Department row)
    {
        foreach (Department dep in departments)
        {
            if (dep == row)
            {
                departments.Remove(row);
                return true;
            }
            if (DeleteRowRecursively(dep.Children, row))
                break;
        }
        return false;
    }
}

public partial class Department : ObservableObject
{
    [ObservableProperty]
    public string name = "";

    [ObservableProperty]
    public string phone = "0";

    [Browsable(false)]
    public bool IsRoot { get; set; } = false;

    public ObservableCollection<Department> Children { get; } = new();

    public bool HasChildren { get { return Children.Count > 0; } }

    public void AddDepartment(Department department)
    {
        Children.Add(department);
        if (Children.Count == 1)
            OnPropertyChanged(nameof(HasChildren));
    }
}

Пример - Как генерировать команды контекстного меню из ViewModel

В этом примере показано, как заполнить меню ячейки строки контрола TreeList элементами, определенными в ViewModel.

treelist-contextmenus-rowcellmenu-fromViewModel-example

Меню ячейки строки (TreeListControlBase.RowCellMenu) заполняется элементами (объектами ToolbarButtonItem) из источника объектов, указанного в коллекции PopupMenu.ItemsSource. В этом примере свойство PopupMenu.ItemsSource привязано к коллекции MenuItems, определенной в модели основного представления, используя следующее выражение привязки:

<mxb:PopupMenu ItemsSource="{Binding DataControl.DataContext.MenuItems}">

Когда для ячейки TreeList отображается PopupMenu, DataContext меню содержит объект Eremex.AvaloniaUI.Controls.DataControl.Visuals.CellData. Объект CellData предоставляет свойство DataControl, которое позволяет вам получить доступ к контролу, для которого отображается меню. Модель основного вида назначается DataContext контрола. Таким образом, синтаксис DataControl.DataContext.MenuItems ссылается на коллекцию MenuItems, определенную в модели main View.

Объект CellData также содержит другие свойства, которые позволяют вам получать доступ к информации, связанной с ячейкой (объекту столбца, строки и т.д.).

Элементы меню инициализируются с использованием стилей. DataContext из элементов меню являются элементами коллекции PopupMenu.ItemsSource. В этом примере свойство PopupMenu.ItemsSource хранит коллекцию объектов MenuItemViewModel. Следующий фрагмент связывает свойства ToolbarButtonItem.Header и ToolbarButtonItem.Command со свойствами MenuItemViewModel.Header и MenuItemViewModel.Command соответственно.

<mxb:PopupMenu.Styles>
    <Style Selector="mxb|ToolbarButtonItem">
        <Setter Property="Header" Value="{Binding Header}"/>
        <Setter Property="Command" Value="{Binding Command}"  />
    </Style>
</mxb:PopupMenu.Styles>

Команде ToolbarButtonItem требуется информация о строке, по которой был произведен щелчок правой кнопкой мыши. Чтобы передать строку данных команде, XAML-код устанавливает свойство ToolbarButtonItem.CommandParameter следующим образом:

xmlns:mxvis="clr-namespace:Eremex.AvaloniaUI.Controls.DataControl.Visuals;
 assembly=Eremex.Avalonia.Controls"

<mxb:PopupMenu.Styles>
    <Style Selector="mxb|ToolbarButtonItem">
        ...
        <Setter Property="CommandParameter" 
         Value="{Binding $parent[mxvis:CellControl].DataContext.Row}"/>
    </Style>
</mxb:PopupMenu.Styles>

Здесь выражение $parent[mxvis:CellControl] обходит логическое дерево, чтобы найти объект CellControl (он является родительским для DataContext ToolbarButtonItem). Объект CellControl.DataContext содержит объект Eremex.AvaloniaUI.Controls.DataControl.Visuals.CellData, который позволяет вам получить доступ к строке данных из свойства CellData.Row.

Полный код приведен ниже.

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"
xmlns:mxb="https://schemas.eremexcontrols.net/avalonia/bars"
xmlns:mxvis="clr-namespace:Eremex.AvaloniaUI.Controls.DataControl.Visuals;
 assembly=Eremex.Avalonia.Controls"

<mxtl:TreeListControl Name="treeList1"
                AutoGenerateColumns="True"
                ItemsSource="{Binding Departments}"
                ChildrenFieldName="Children"
                HasChildrenFieldName="HasChildren"
                ExpandStateFieldName="IsExpanded"
                FocusedItem="{Binding SelectedDepartment, Mode=TwoWay}"
            >
    <mxtl:TreeListControl.RowCellMenu>
        <mxb:PopupMenu ItemsSource="{Binding DataControl.DataContext.MenuItems}">
            <mxb:PopupMenu.Styles>
                <Style Selector="mxb|ToolbarButtonItem">
                    <Setter Property="Header" Value="{Binding Header}"/>
                    <Setter Property="Command" Value="{Binding Command }"  />
                    <Setter Property="CommandParameter" 
                     Value="{Binding $parent[mxvis:CellControl].DataContext.Row}"/>
                </Style>
            </mxb:PopupMenu.Styles>
        </mxb:PopupMenu>
    </mxtl:TreeListControl.RowCellMenu>
</mxtl:TreeListControl>
public partial class MainView : UserControl
{
    MainViewModel viewModel = new MainViewModel();

    public MainView()
    {
        DataContext = viewModel;

        Department depOperations = new Department() 
        { 
            Name = "Operations", Phone = "1110", IsRoot = true 
        };
        Department depManufacturing = new Department() 
        { 
            Name = "Manufacturing", Phone = "1111" 
        };
        Department depQuality = new Department() 
        { 
            Name = "Quality", Phone = "1112" 
        };
        depOperations.Children.Add(depManufacturing);
        depOperations.Children.Add(depQuality);

        Department depMarketing = new Department() 
        { 
            Name = "Marketing", Phone = "3120", IsRoot = true 
        };
        Department depSales = new Department() 
        { 
            Name = "Sales", Phone = "3121" 
        };
        Department depCRM = new Department() 
        { 
            Name = "CRM", Phone = "3122" 
        };
        depMarketing.Children.Add(depSales);
        depMarketing.Children.Add(depCRM);

        Department depAccountsAndFinance = new Department() 
        { 
            Name = "Accounts & Finance", Phone = "5780", IsRoot = true 
        };
        Department depAccounts = new Department() 
        { 
            Name = "Sales", Phone = "5781" 
        };
        Department depFinance = new Department() 
        { 
            Name = "Finance", Phone = "5782" 
        };
        depAccountsAndFinance.Children.Add(depAccounts);
        depAccountsAndFinance.Children.Add(depFinance);

        Department depHumanResources = new Department() 
        { 
            Name = "Human Resources", Phone = "7370", IsRoot = true 
        };
        Department depHR = new Department() 
        { 
            Name = "HR", Phone = "7370" 
        };
        depHumanResources.Children.Add(depHR);

        viewModel.Departments.Add(depOperations);
        viewModel.Departments.Add(depMarketing);
        viewModel.Departments.Add(depAccountsAndFinance);
        viewModel.Departments.Add(depHumanResources);

        InitializeComponent();
    }
}

public partial class MainViewModel : ViewModelBase
{
    [ObservableProperty]
    Department? selectedDepartment;

    public MainViewModel() 
    {
        MenuItemViewModel menuItem1 = new MenuItemViewModel();
        menuItem1.Header = "Add Child Dep";
        menuItem1.Command = new RelayCommand<Department>(AddChildRow);
        MenuItems.Add(menuItem1);

        MenuItemViewModel menuItem2 = new MenuItemViewModel();
        menuItem2.Header = "Hide Dep";
        menuItem2.Command = new RelayCommand<Department>(HideRow);
        MenuItems.Add(menuItem2);
    }

    public ObservableCollection<Department> Departments { get; } = new();

    public ObservableCollection<MenuItemViewModel> MenuItems { get; } = new();

    [RelayCommand]
    void AddChildRow(Department? parentRow)
    {
        if (parentRow == null) return;

        Department newDepartment = new() 
        { 
            Name = "New dep", Phone = "0000" 
        };
        parentRow.AddDepartment(newDepartment);
        parentRow.IsExpanded = true;
        SelectedDepartment = newDepartment;
    }

    [RelayCommand]
    void HideRow(Department? row)
    {
        //...
    }
}

public partial class MenuItemViewModel : ObservableObject
{
    [ObservableProperty]
    string? header;

    [ObservableProperty]
    ICommand? command;
}

public partial class Department : ObservableObject
{
    [ObservableProperty]
    public string name = "";

    [ObservableProperty]
    public string phone = "0";

    [ObservableProperty]
    public bool isExpanded;

    [Browsable(false)]
    public bool IsRoot { get; set; } = false;

    public ObservableCollection<Department> Children { get; } = new();

    public bool HasChildren => Children.Count > 0;

    public void AddDepartment(Department department)
    {
        Children.Add(department);
        if (Children.Count == 1)
            OnPropertyChanged(nameof(HasChildren));
    }
}

Настройка меню при отображении

Вы можете обработать событие PopupMenu.Opening для динамической настройки меню TreeList. Событие происходит, когда вот-вот отобразится всплывающее меню.

Пример - Как отобразить контекстное меню для первого столбца

В следующем примере свойству TreeListControlBase.RowCellMenu присваивается пустое значение PopupMenu, а затем обрабатывается событие PopupMenu.Opening для заполнения меню элементами, когда пользователь щелкает правой кнопкой мыши ячейки в первом видимом столбце TreeList. Меню остается пустым (и, следовательно, не отображается), когда пользователь щелкает правой кнопкой мыши в других столбцах.

Созданное меню содержит кнопку-переключатель "Show/Hide Root Indent", которая переключает видимость отступа TreeList (свойство TreeListControlBase.ShowRootIndent).

treelist-contextmenus-customizeonshowing

<mxtl:TreeListControl Name="treeList1" ...>
    <mxtl:TreeListControl.RowCellMenu>
        <mxb:PopupMenu Opening="RowCellMenuOpening"/>
    </mxtl:TreeListControl.RowCellMenu>
</mxtl:TreeListControl>
void RowCellMenuOpening(object sender, CancelEventArgs e)
{
    if (sender == null) return;
    PopupMenu menu = sender as PopupMenu;
    menu.Items.Clear();

    CellData cellData = menu.DataContext as CellData;
    TreeListControl control = cellData.DataControl as TreeListControl;
    TreeListColumn column = cellData.Column as TreeListColumn;
    //// Access the underlying data row, when required.
    //object dataRow = cellData.Row;

    if(column.VisibleIndex == 0)
    {
        ToolbarCheckItem btn1 = new ToolbarCheckItem();
        btn1.IsChecked = control.ShowRootIndent;
        btn1.Header = (control.ShowRootIndent) ? "Hide Root Indent" : "Show Root Indent";
        btn1.Command = new RelayCommand<TreeListControl>(ShowRootIndentCommand);
        btn1.CommandParameter = control;
        menu.Items.Add(btn1);
    }
}

[RelayCommand]
void ShowRootIndentCommand(TreeListControl treeList)
{
    treeList.ShowRootIndent = !treeList.ShowRootIndent;
}

Отображение контекстного меню для контролов, использующих Attached-свойство ToolbarManager в ToolbarManager в ToolbarManager в ToolbarManager в ToolbarManager.

Компонент Eremex.AvaloniaUI.Controls.Bars.ToolbarManager предоставляет attached-свойство ContextPopup, которое позволяет назначать контекстное меню любому контролу, включая TreeList и TreeView. Это контекстное меню отображается для регионов TreeList/TreeView, в которых нет контекстных меню по умолчанию, и для регионов с пустыми меню по умолчанию.

Пример - Как назначить контекстное меню, используя attached-свойство ToolbarManager.ContextPopup.

Следующий код использует attached-свойство ToolbarManager.ContextPopup для указания контекстного меню для контрола TreeList. Меню содержит переключающий элемент меню Show Column Header Panel/Hide Column Header Panel, который переключает видимость опции TreeListControl.ShowColumnHeaders.

treelist-contextmenus-toolbarmanager-example

xmlns:mxtl="https://schemas.eremexcontrols.net/avalonia/treelist"

<mxtl:TreeListControl Name="treeList1">
    <mxtl:TreeListControl.Styles>
        <Style Selector="mxtl|TreeListControl">
            <Setter Property="mxb:ToolbarManager.ContextPopup" >
                <Template>
                    <mxb:PopupMenu Tag="treeList1">
                        <mxb:ToolbarCheckItem Header="Show Column Header Panel" 
                         IsChecked="{Binding $parent[mxtl:TreeListControl].ShowColumnHeaders, 
                          Mode=TwoWay}" 
                         IsVisible="{Binding !$parent[mxtl:TreeListControl].ShowColumnHeaders}"/>
                        <mxb:ToolbarCheckItem Header="Hide Column Header Panel" 
                        IsChecked="{Binding $parent[mxtl:TreeListControl].ShowColumnHeaders, 
                         Mode=TwoWay}" 
                        IsVisible="{Binding $parent[mxtl:TreeListControl].ShowColumnHeaders}"/>
                    </mxb:PopupMenu>
                </Template>
            </Setter>
        </Style>
    </mxtl:TreeListControl.Styles>
</mxtl:TreeListControl>



* Эта страница была создана автоматически с помощью сервиса машинного перевода Яндекс Переводчик.