获取 ToolBar Button 以触发所选 TreeView 项的方法
Get ToolBar Button to trigger a method for the selected TreeView item
我正在编写一个 MVVM 应用程序(使用 Caliburn.Micro),它加载 Active Directory 树、显示所选 OU 的计算机并在这些计算机上运行 WMI 查询。我想创建一个工具栏按钮,它基本上刷新计算机的数据(即重新运行 WMI 查询)。我正在努力弄清楚如何让我的工具栏按钮为所选项目 (OUModel
) 触发 QueryRemoteComputers()
。我已经尽可能简化了代码,所以希望这很容易阅读。
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 OU 模型
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 通过以下方式绑定到 TreeView 的 SelectedItem:
<ListView Grid.Row="1" Grid.Column="2" ItemsSource="{Binding SelectedItem.Computers, ElementName=ADTree, Mode=OneWay}">
我已经找到了一种使用 lambda 表达式的方法。
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();
}
}
我正在编写一个 MVVM 应用程序(使用 Caliburn.Micro),它加载 Active Directory 树、显示所选 OU 的计算机并在这些计算机上运行 WMI 查询。我想创建一个工具栏按钮,它基本上刷新计算机的数据(即重新运行 WMI 查询)。我正在努力弄清楚如何让我的工具栏按钮为所选项目 (OUModel
) 触发 QueryRemoteComputers()
。我已经尽可能简化了代码,所以希望这很容易阅读。
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 OU 模型
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 通过以下方式绑定到 TreeView 的 SelectedItem:
<ListView Grid.Row="1" Grid.Column="2" ItemsSource="{Binding SelectedItem.Computers, ElementName=ADTree, Mode=OneWay}">
我已经找到了一种使用 lambda 表达式的方法。
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();
}
}