Кнопка «Получить панель инструментов» для вызова метода для выбранного элемента TreeView - PullRequest
0 голосов
/ 28 января 2020

Я пишу приложение MVVM (используя Caliburn.Micro), которое загружает дерево Active Directory, отображает компьютеры для выбранного OU и выполняет запросы WMI на этих компьютерах. Я хочу создать кнопку панели инструментов, которая в основном обновляет данные для компьютеров (т. Е. Повторно запускает запросы WMI). Я изо всех сил пытаюсь понять, как заставить кнопку на панели инструментов запускать QueryRemoteComputers() для выбранного элемента (OUModel). Я упростил код до максимально возможного количества кода, поэтому, надеюсь, его легко прочитать.

Просмотреть модель для TreeView

class TreeViewItemViewModel : ITreeViewItemViewModel
{
    static readonly TreeViewItemViewModel dummyChild = new TreeViewItemViewModel();
    private bool isExpanded;

    public TreeViewItemViewModel Parent { get; set; }
    public BindableCollection<TreeViewItemViewModel> Children { get; set; }
    public bool IsExpanded { 
        get
        { return isExpanded; }
        set
        { // Expand parents, remove dummy child etc }
    }
    public virtual bool IsSelected { get; set; }
    // A few more things like virtual LoadChildren etc
}

Просмотреть модель

class ADTreeViewModel : TreeViewItemViewModel
{

    public ADTreeViewModel(LaunchRequest launchRequest) : base(null, false) // Loading the top level OUs now, so setting lazyLoadChildren to false (it will be set to true for the children later)
    {
        LoadChildren();
    }

    protected override void LoadChildren()
    {
        // Fetch top level OUs from AD

        // Add each OU to the TreeView
        foreach (var ou in ous)
        {
            if (ou.Members["ObjectClass"].Value.ToString() == "organizationalUnit")
            {
                base.Children.Add(new OUModel(ou.Members["Name"].Value.ToString(), ou.Members["DistinguishedName"].Value.ToString(), this));
            }
        }

    }

    #region Toolbar Buttons
    public void UpdateComputerStatus() // <<< Bound to toolbar button Click event
    {
        // QueryRemoteComputers(); // How can I call this for the selected tree view item/OUModel
    }
    #endregion // Toolbar Buttons

}

Модель для подразделений Active Directory

class OUModel : TreeViewItemViewModel
{
    private bool isSelected = false;

    #region Bindable Properties
    public string Name { get; set; }
    public string DistinguishedName { get; set; }
    public List<RemoteComputer> Computers { get; set; } = new List<RemoteComputer>();
    public override bool IsSelected
    {
        get { return isSelected; }
        set
        {
            if (isSelected != value)
            {
                isSelected = value;

                if (tokenSource != null) // If any 'QueryRemoteComputers' tasks are still running, cancel them (Happens if the user changes OU before queries are completed)
                {
                    tokenSource.Cancel(); 
                }

                LoadComputers();
                QueryRemoteComputers();
            }
        }
    }
    #endregion // Bindable Properties

    public OUModel(string name, string distinguishedName, TreeViewItemViewModel parent) : base(parent, true)
    {
        Name = name;
        DistinguishedName = distinguishedName;
    }

    private void LoadComputers()
    {
        // Fetch computers in OU
        foreach (var computer in comps)
        {
            Computers.Add(new RemoteComputer(computer.Members["Name"].Value.ToString(), computer.Members["DNSHostName"].Value.ToString(), computer.Members["DistinguishedName"].Value.ToString()));
        }
    }

    private void QueryRemoteComputers() // <<< I want to call this
    {
        foreach (RemoteComputer computer in Computers)
        {
            // Run WMI queries on remote computers and store the results
            computer.Property = etc;
        }
    }
}

TreeView связан через (т.е. ADTreeViewModel.Children):

<TreeView Grid.Row="1" Grid.Column="0" x:Name="ADTree" ItemsSource="{Binding Children}">

Компьютеры ListView привязаны к SelectedItem TreeView через:

<ListView Grid.Row="1" Grid.Column="2" ItemsSource="{Binding SelectedItem.Computers, ElementName=ADTree, Mode=OneWay}">

1 Ответ

0 голосов
/ 29 января 2020

Мне удалось найти способ сделать это, используя лямбда-выражение.

public void UpdateComputerStatus() // <<< Bound to toolbar button Click event
{
    TreeViewItemViewModel selectedItem = Children.Where(c => c.IsSelected == true).FirstOrDefault();
    OUModel ou = selectedItem as OUModel;

    if (ou != null)
    {
        ou.QueryRemoteComputers();
    }  
}
...