Я пишу приложение 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}">