Как отправить информацию GUI обратно в текстовый текст - PullRequest
0 голосов
/ 28 августа 2018

Первая информация Я не использую C # (пока)!


Я недавно начал программировать графический интерфейс в PowerShell и переключился с WinForm на WPF две недели назад. Теперь у меня есть простой вопрос, так что ни один учебник даже не удосужился его объявить.

Как получить информацию о действиях, которые я сделал в графическом интерфейсе, для работы с ними ?? Существует множество руководств по привязке моих данных, чтобы они отображались в моем графическом интерфейсе. Но теперь я хочу использовать это наоборот:

  • У меня есть список, связанный с индексом моего текстового контекста.
  • Textbox.Text привязан к выбранному элементу указанного списка.
  • Теперь я хочу вернуть этот предмет в мой текстовый текст.

Пока что мой текст данных определяется как:

$DataContext = New-Object System.Collections.ObjectModel.ObservableCollection[Object]

И добавил несколько переменных

$DataContext.Add($A.VMs)
$DataContext.Add($A.VM)
.
.
.

Хуже всего то, что я пытаюсь использовать его в дополнительном потоке, который должен обрабатывать только мой графический интерфейс, используя этот учебник: https://learn -powershell.net / 2012/10/14 / powershell-and -wpf-писание-данных в-а-ш-с-а-разному-пространство выполнения /

Добавление второй привязки к Textbox не совсем работает. Даже не Multibinding:

<TextBox.Text>
  <MultiBinding StringFormat="{}{0}">
     <Binding Path="SelectedItem"  ElementName ="ListBoxVM" Mode="OneWay" />
     <Binding Path="[1]" Mode="OneWayToSource" />
   </MultiBinding>  
</TextBox.Text>

Моей следующей идеей было бы добавить привязку к текстовому тексту данных [1] в коде, чтобы связать его с TextBox.Text. Однако в этой настройке datacontext не имеет свойства, которое я мог бы связать.


Редактировать: меня попросили больше кода, так что вот оно:

    Add-Type -AssemblyName PresentationCore,PresentationFramework,WindowsBase,system.windows.forms,System.Collections

# Creating Hashtable as base for Multithreading 
$A = [hashtable]::Synchronized(@{})

# Here is the scriptblock for the Thread containing my XAML

$GUILayerScript = {
[xml]$xaml = @"
<Window 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    x:Name="Window" Title="VM Manager" WindowStartupLocation = "CenterScreen" Language ="de-de"
    SizeToContent = "WidthAndHeight" ShowInTaskbar = "True"  Background = "Azure" ResizeMode = "NoResize" >
    <StackPanel x:Name = "StackHorz"  Margin = "5" Orientation = "Horizontal"  >
          <StackPanel x:Name = "StackLinks" Margin = "0,0,5,0" >
            <Button x:Name = "LoginButton" ToolTip = "Benutzer wechseln">
                <WrapPanel>
                    <TextBlock Text = "Logged in as: " />
                    <TextBlock x:Name ="LoginButtonText" Text = "{Binding Path=[5]}"/>
                </WrapPanel>    
            </Button>

            <ListBox x:Name = "ListBoxVM" ItemsSource = "{Binding Path=[0]}" ToolTip = "VM auswählen" MinHeight = "150" MinWidth = "100" Margin = "0,5,0,5" />
            <Button x:Name = "ButtonVMRefresh" Content ="Aktualisieren" ToolTip = "Aktualisiert die Anzeige aller VMs" />
          </StackPanel>
          <StackPanel x:Name = "StackRechts" >

            <Grid x:Name = "Grid" MinHeight = "220" MinWidth = "150" Background="azure"  Margin = "0,0,0,5" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width = "*"/>

                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height = "Auto"/>
                    <RowDefinition Height = "Auto"/>
                    <RowDefinition Height = "Auto"/>
                    <RowDefinition Height = "Auto"/>
                    <RowDefinition Height = "Auto"/>
                    <RowDefinition Height = "Auto"/>
                </Grid.RowDefinitions>
                <Label Content = "Chosen VM:"  Grid.Column = "0" Grid.Row = "0" HorizontalAlignment="Center" VerticalAlignment="Center" />
                <TextBox x:Name = "VMChoiceText"  Grid.Column = "0" Grid.Row = "1" Height = "Auto" ToolTip = "Die aktuell Ausgewählte VM" IsReadOnly = "True" Margin = "10">
                   <TextBox.Text>
                     <MultiBinding StringFormat="{}{0}">
                        <Binding Path="SelectedItem"  ElementName ="ListBoxVM" Mode="OneWay" />
                        <Binding Path="[1]" Mode="OneWayToSource" />
                     </MultiBinding>  
                   </TextBox.Text>
                </TextBox> 
                <Label Content = "Status:" Grid.Column = "0" Grid.Row = "2" HorizontalAlignment="Center" VerticalAlignment="Center" />
                <TextBox x:Name = "StatusText" Grid.Column = "0" Grid.Row = "3"  Height = "Auto" ToolTip = "Status der VM" IsReadOnly = "True" Margin = "10,5,10,15"/>
                <Button x:Name ="ButtonVMStart" Content = "VM start" Grid.Column = "0" Grid.Row = "4" ToolTip ="Startet die ausgewähle VM"  Margin = "10"/>
                <Button x:Name ="ButtonVMStop" Content = "VM stop" Grid.Column = "0" Grid.Row = "5" ToolTip ="Fährt die ausgewähle VM herunter"  Margin = "10"/>

            </Grid>
            <TextBlock x:Name="TextBoxConsole" Height = "75" Background = "darkblue" Foreground = "white" />
          </StackPanel>
     </StackPanel>
</Window>

"@

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Window=[Windows.Markup.XamlReader]::Load( $reader )
$A.Window = $Window
$NamedElements = @( #"StackHorz",
                    #"StackLinks",
                    #"StackRechts",
                    "LoginButton",
                    "LoginButtonText",
                    #"Expander",
                    "UserTextBox",
                    "PasswordBox",
                    "LoginExec",
                    "ListBoxVM",
                   # "Grid", 
                    "ButtonVMRefresh", 
                    "TextBoxConsole", 
                    "VMChoiceText", 
                    "StatusText", 
                    "ButtonVMStart", 
                    "ButtonVMStop"

                  )
try{
$NamedElements | ForEach-Object {$A.Add("$_" , $($Window.FindName("$_")))}
}catch{}


########## Here is the DataContext set for the XAML
$A.Window.DataContext = $A.DataContext


[void]$a.Window.ShowDialog()
}

# Here I create my DataContext and give it some content
$A.VMs = 1..5
$A.MyName = $env:USERNAME

$DataContext = New-Object System.Collections.ObjectModel.ObservableCollection[Object]
$A.DataContext = $DataContext
$DataContext.Add($A.VMs)
$DataContext.Add($A.VM)
$DataContext.Add($A.some)
$DataContext.Add($A.other)
$DataContext.Add($A.stuff)
$DataContext.Add($A.MyName)


# Thread magic is happening here

#region Thread Control
$initialSessionState = [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault()
$newRunspace =[runspacefactory]::CreateRunspace($initialSessionState)
$newRunspace.ApartmentState = "STA"
$newRunspace.Open()
$newRunspace.SessionStateProxy.SetVariable("A",$A) 
$newRunspace.SessionStateProxy.SetVariable("DataContext",$($A.DataContext))

$Gui = [powershell]::Create()
[void]$Gui.addscript($global:GUILayerScript)
$Gui.Runspace = $newRunspace
$GuiThread = $Gui.beginInvoke()

#endregion

1 Ответ

0 голосов
/ 31 августа 2018

Сейчас я использую обходной путь, когда я создаю обработчик событий в codebehinde, чтобы записать сделанные пользователем изменения в GUI обратно в мою хеш-таблицу:

$A.VMChoiceText.add_TextChanged({$A.DataContext[1] = $A.VMChoiceText.Text})

Однако я все еще открыт для лучших решений.

...