Как я могу обновить Combobox WPF, если раскрывающийся список закрыт на другом Combobox? - PullRequest
0 голосов
/ 21 мая 2019

Я недавно начал подбирать C #, поскольку в компании требовались некоторые исполняемые файлы, которые будут запускать предопределенные наборы команд PowerShell. Я знаю ...

Это не тот модуль, который я использую, но ниже я написал упрощенный пример проблемы, с которой я сталкиваюсь при использовании модуля activedirectory.

Вот xaml.

<Window x:Class="ADTool.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ADTool"
        mc:Ignorable="d"
        Title="AD Administration" Height="270" Width="500" ResizeMode="CanMinimize">
    <Grid Background="Crimson" Width="494" Height="241">
        <TextBlock Margin="20,90,0,0" TextWrapping="Wrap" FontWeight="Bold" FontSize="20" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120" TextAlignment="Right"><Run FontFamily="Calibri" Text="AD Group" Foreground="Azure"/></TextBlock>
        <ComboBox Name ="ADGroup" Height="25" Margin="150,90,0,0" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" FontSize="12" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" Width="324" DropDownClosed="ADGroup_DropDownClosed"/>
        <TextBlock Margin="20,135,0,0" TextWrapping="Wrap" FontWeight="Bold" FontSize="20" Height="25" VerticalAlignment="Top" HorizontalAlignment="Left" Width="120" TextAlignment="Right"><Run FontFamily="Calibri" Text="ADGroupMember" Foreground="Azure"/></TextBlock>
        <ComboBox Name ="ADGroupMember" Height="25" Margin="150,135,0,0" VerticalAlignment="Top" BorderBrush="Black" BorderThickness="1" FontSize="12" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" HorizontalAlignment="Left" Width="324"/>
        <Button Name="BtnAdd" Content="Add" Margin="32,180,0,0" BorderBrush="Black" FontWeight="Bold" Background="LightGray" Foreground="Black" BorderThickness="1" HorizontalAlignment="Left" Width="100" Height="25" VerticalAlignment="Top"/>
        <Button Name="BtnRemove" Content="Remove" Margin="142,180,0,0" BorderBrush="Black" FontWeight="Bold" Background="LightGray" Foreground="Black" BorderThickness="1" HorizontalAlignment="Left" Width="100" Height="25" VerticalAlignment="Top"/>
        <Button Name="BtnShow" Content="Show" Margin="252,180,0,0" BorderBrush="Black" FontWeight="Bold" Background="LightGray" Foreground="Black" BorderThickness="1" HorizontalAlignment="Left" Width="100" Height="25" VerticalAlignment="Top"/>
        <Button Name="BtnQuit" Content="Quit" Margin="362,180,0,0" BorderBrush="Black" FontWeight="Bold" Background="LightGray" Foreground="Black" BorderThickness="1" HorizontalAlignment="Left" Width="100" Height="25" VerticalAlignment="Top"/>
    </Grid>
</Window>

А вот и C #.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Windows;

namespace ADTool
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // Initiate new PowerShell session and import modules
            string[] psModule = { "activedirectory" };
            var powerShell = NewPowerShellSession(psModule);

            // Add list of AD Groups
            var groups = ListADGroup(powerShell);
            ADGroup.ItemsSource = groups;
        }

        // New PowerShell Session, optionally with module(s)
        private PowerShell NewPowerShellSession(String[] PSModule = null)
        {
            // Define our PowerShell Session
            PowerShell powerShell = PowerShell.Create();

            // Add a runspace to import the module if required.
            if (PSModule != null)
            {
                InitialSessionState initial = InitialSessionState.CreateDefault();
                initial.ImportPSModule(PSModule);
                Runspace runspace = RunspaceFactory.CreateRunspace(initial);
                runspace.Open();
                powerShell.Runspace = runspace;
            } 
            return powerShell;
        }

        // PowerShell function
        private Collection<PSObject> RunPSASync(PowerShell ps, String PSCommand, IDictionary<String, Object> Parameters, String Property)
        {
            // Sleep two seconds before proceeding.
            ps.AddCommand("Start-Sleep").AddParameter("Seconds", 2).AddStatement();

            // Run our command adding the parameters one by one and then pipe in to Out-String.
            ps.AddCommand(PSCommand);
            if (Parameters != null)
            {
                foreach (var key in Parameters.Keys)
                {
                    ps.AddParameter(key, Parameters[key]);
                }
            }
            // List a selected property
            if (Property != null)
            {
                ps.AddCommand("Select-Object").AddParameter("ExpandProperty", Property);
            }

            // Invoke our command asynchronously and return the objects.
            IAsyncResult async = ps.BeginInvoke();
            var returnCollection = new Collection<PSObject>();
            foreach (PSObject obj in ps.EndInvoke(async))
            {
                returnCollection.Add(obj);
            }
            return returnCollection;
        }

        // PowerShell function with pipeline
        private Collection<PSObject> RunPSASyncPipe(PowerShell ps, String PSCommand, IDictionary<String, Object> Parameters, String PSCommand2, IDictionary<String, Object> Parameters2, String Property)
        {
            // Sleep two seconds before proceeding.
            ps.AddCommand("Start-Sleep").AddParameter("Seconds", 2).AddStatement();

            // Run our command adding the parameters one by one and then pipe in to Out-String.
            ps.AddCommand(PSCommand);
            if (Parameters != null)
            {
                foreach (var key in Parameters.Keys)
                {
                    ps.AddParameter(key, Parameters[key]);
                }
            }

            // Add the second command in the pipeline
            ps.AddCommand(PSCommand2);
            if (Parameters2 != null)
            {
                foreach (var key in Parameters2.Keys)
                {
                    ps.AddParameter(key, Parameters2[key]);
                }
            }

            // List a selected property
            if (Property != null)
            {
                ps.AddCommand("Select-Object").AddParameter("ExpandProperty", Property);
            }

            // Invoke our command asynchronously and return the objects.
            IAsyncResult async = ps.BeginInvoke();
            var returnCollection = new Collection<PSObject>();
            foreach (PSObject obj in ps.EndInvoke(async))
            {
                returnCollection.Add(obj);
            }
            return returnCollection;
        }

        // List all AD Groups in a specific OU
        private IEnumerable<PSObject> ListADGroup(PowerShell ps)
        {
            // Define Searchbase
            IDictionary<String, Object> parameters = new Dictionary<String, Object>();
            parameters.Add("Filter", "*");
            parameters.Add("SearchBase", "OU=SomeOtherOU,OU=topOU,DC=blah,DC=com");

            var adGroups = RunPSASync(ps, "Get-ADGroup", parameters, "Name");
            return adGroups;
        }

        // Action when ADGroup combobox gets closed
        private void ADGroup_DropDownClosed(PowerShell ps)
        {
            // Collect the currently selected Edge device
            string adGroupName = ADGroup.SelectedItem.ToString();
            IDictionary<String, Object> groupParameters = new Dictionary<String, Object>();
            groupParameters.Add("Filter", "*");
            groupParameters.Add("SearchBase", "OU=SomeOtherOU,OU=topOU,DC=blah,DC=com");

            IDictionary<String, Object> memberParameters = new Dictionary<String, Object>();
            memberParameters.Add("Name", adGroupName);

            var adMembers = RunPSASyncPipe(ps, "Get-ADGroup", groupParameters, "Get-ADGroupMember", memberParameters, "name");
            ADGroupMember.ItemsSource = adMembers;
        }
    }
}

А вот как бы я это сделал, если бы мне было разрешено предоставлять людям файл .ps1.

$xaml = "C:\Scripts\somefile.xml"
$wpf = [System.Xml.XmlDocument](Get-Content $xaml)
$reader = (New-Object System.Xml.XmlNodeReader $wpf)
$app = [System.Windows.Markup.XamlReader]::Load($reader)

# Create variables for the named nodes.
$wpf.SelectNodes("//*[@Name]") | ForEach-Object {
    New-Variable -Name $_.Name -Value $app.FindName($_.Name) -Scope Global -Force
}

$ADGroup.Add_DropDownClosed({
    # do stuff...
})

Я подозреваю, что мне не хватает чего-то, чтобы активировать действие DropDownClosed, и я пытался добавить его в XAML, но это не сработало. Я искал другие варианты, но если бы кто-нибудь мог пощадить новичка в C #, то я был бы очень признателен. Я знаком с .NET, но, похоже, он работает не так, как я ожидаю в PowerShell.

(Прошу прощения за любые ошибки в моем C # тоже)

1 Ответ

0 голосов
/ 21 мая 2019

Это работает как ожидалось. Я думаю, что проблема заключалась в том, что я пытался передать сеанс PowerShell от метода к методу, когда все, что мне нужно было сделать, это определить его в классе, а затем следовать документации здесь - https://docs.microsoft.com/en-us/dotnet/api/system.windows.controls.combobox.dropdownclosed?view=netframework-4.8

Надеюсь, это поможет кому-то, кто новичок в этом, как я.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Runspaces;
using System.Security;
using System.Windows;

namespace ADTool
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private PowerShell _powershell;
        public PowerShell PowerShell
        {
            get { return _powershell; }
            set { _powershell = value; }
        }

        public MainWindow()
        {
            InitializeComponent();

            // Initiate new PowerShell session and import modules
            string[] psModule = { "activedirectory" };
            PowerShell = NewPowerShellSession(psModule);

            // Add list of AD Groups
            var groups = ListADGroup();
            ADGroup.ItemsSource = groups;
        }

        // New PowerShell Session, optionally with module(s)
        private PowerShell NewPowerShellSession(String[] PSModule = null)
        {
            // Define our PowerShell Session
            PowerShell powerShell = PowerShell.Create();

            // Add a runspace to import the module if required.
            if (PSModule != null)
            {
                InitialSessionState initial = InitialSessionState.CreateDefault();
                initial.ImportPSModule(PSModule);
                Runspace runspace = RunspaceFactory.CreateRunspace(initial);
                runspace.Open();
                powerShell.Runspace = runspace;
            } 
            return powerShell;
        }

        // PowerShell function
        private Collection<PSObject> RunPSASync(String PSCommand, IDictionary<String, Object> Parameters, String Property)
        {
            // Sleep two seconds before proceeding.
            PowerShell.AddCommand("Start-Sleep").AddParameter("Seconds", 2).AddStatement();

            // Run our command adding the parameters one by one and then pipe in to Out-String.
            PowerShell.AddCommand(PSCommand);
            if (Parameters != null)
            {
                foreach (var key in Parameters.Keys)
                {
                    PowerShell.AddParameter(key, Parameters[key]);
                }
            }
            // List a selected property
            if (Property != null)
            {
                PowerShell.AddCommand("Select-Object").AddParameter("ExpandProperty", Property);
            }

            // Invoke our command asynchronously and return the objects.
            IAsyncResult async = PowerShell.BeginInvoke();
            var returnCollection = new Collection<PSObject>();
            foreach (PSObject obj in PowerShell.EndInvoke(async))
            {
                returnCollection.Add(obj);
            }
            return returnCollection;
        }

        // PowerShell function with pipeline
        private Collection<PSObject> RunPSASyncPipe(String PSCommand, IDictionary<String, Object> Parameters, String PSCommand2, IDictionary<String, Object> Parameters2, String Property)
        {
            // Sleep two seconds before proceeding.
            PowerShell.AddCommand("Start-Sleep").AddParameter("Seconds", 2).AddStatement();

            // Run our command adding the parameters one by one and then pipe in to Out-String.
            PowerShell.AddCommand(PSCommand);
            if (Parameters != null)
            {
                foreach (var key in Parameters.Keys)
                {
                    PowerShell.AddParameter(key, Parameters[key]);
                }
            }

            // Add the second command in the pipeline
            PowerShell.AddCommand(PSCommand2);
            if (Parameters2 != null)
            {
                foreach (var key in Parameters2.Keys)
                {
                    PowerShell.AddParameter(key, Parameters2[key]);
                }
            }

            // List a selected property
            if (Property != null)
            {
                PowerShell.AddCommand("Select-Object").AddParameter("ExpandProperty", Property);
            }

            // Invoke our command asynchronously and return the objects.
            IAsyncResult async = PowerShell.BeginInvoke();
            var returnCollection = new Collection<PSObject>();
            foreach (PSObject obj in PowerShell.EndInvoke(async))
            {
                returnCollection.Add(obj);
            }
            return returnCollection;
        }

        // List all AD Groups in a specific OU
        private IEnumerable<PSObject> ListADGroup()
        {
            // Define Searchbase
            IDictionary<String, Object> parameters = new Dictionary<String, Object>();
            parameters.Add("Filter", "*");
            parameters.Add("SearchBase", "OU=SomeOtherOU,OU=topOU,DC=blah,DC=com");

            var adGroups = RunPSASync("Get-ADGroup", parameters, "Name");
            return adGroups;
        }

        // Action when ADGroup combobox gets closed
        private void ADGroup_DropDownClosed(object sender, EventArgs e)
        {
            // Collect the currently selected Edge device
            string adGroupName = ADGroup.SelectedItem.ToString();
            IDictionary<String, Object> groupParameters = new Dictionary<String, Object>();
            groupParameters.Add("Filter", "*");
            groupParameters.Add("SearchBase", "OU=SomeOtherOU,OU=topOU,DC=blah,DC=com");

            IDictionary<String, Object> memberParameters = new Dictionary<String, Object>();
            memberParameters.Add("Name", adGroupName);

            var adMembers = RunPSASyncPipe("Get-ADGroup", groupParameters, "Get-ADGroupMember", memberParameters, "name");
            ADGroupMember.ItemsSource = adMembers;
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...