Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   WPF GUI и общие параметры у элементов (http://forum.oszone.net/showthread.php?t=342212)

Charg 16-09-2019 16:28 2888220

WPF GUI и общие параметры у элементов
 
Пробую WPF, есть у меня форма с множеством элементов TextBox и для всех их мне нужно применить какой-то стандартный параметр, например Width="auto" Height="auto"

Можно ли как-то собрать все эти текстбоксы в кучу, применить на эту кучу параметр, а текстбоксы все эти параметры унаследовали бы?

Аналогичный вопрос к ивентам - нужно на каждый из этих текстбоксов применить мою функцию на ивент TextChanged (так по крайней мере на windows forms называлось, может тут ContentChanges или нечто подобное). И снова таки, как-то можно одним действием добавить обработку этого ивента на все текстбоксы?

Serguei Kouzmine 17-09-2019 18:33 2888364

вот специально для вас гуглил гуглил и нагуглил

Код:


#requires -version 2

$so = [hashtable]::Synchronized(@{
  'Result' = '';
  'Window' = [System.Windows.Window]$null;
  'TextBox' = [System.Windows.Controls.TextBox]$null;
})
$so.Result = ''
$rs = [runspacefactory]::CreateRunspace()
$rs.ApartmentState = 'STA'
$rs.ThreadOptions = 'ReuseThread'
$rs.Open()

Add-Type -AssemblyName PresentationFramework
[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="Example with Text Boxes" Height="400" Width="300">
  <Grid>
    <StackPanel Name="StackPanel1" Margin="0,0,0,0">
      <Expander Header="Name" Margin="0,0,0,0" Name="Expander1" IsExpanded="True">
        <StackPanel Margin="20,0,0,0">
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">First Name</Label>
            <TextBox Height="25" Width="147" x:Name="First_Name"/>
          </StackPanel>
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">Last Name</Label>
            <TextBox Height="25" Width="147" x:Name="Last_Name"/>
          </StackPanel>
        </StackPanel>
      </Expander>
      <Separator/>
      <Expander Header="Address" Margin="0,0,0,0" IsExpanded="True">
        <StackPanel Margin="20,0,0,0">
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">Street</Label>
            <TextBox Height="25" Width="147" x:Name="Street"/>
          </StackPanel>
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">City</Label>
            <TextBox Height="25" Width="147" x:Name="City"/>
          </StackPanel>
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">State</Label>
            <TextBox Height="25" Width="147"/>
          </StackPanel>
          <StackPanel Height="Auto" Width="Auto" Orientation="Horizontal">
            <Label Height="25.96" Width="84">Zip</Label>
            <TextBox Height="25" Width="147" x:Name="Zip"/>
          </StackPanel>
        </StackPanel>
      </Expander>
      <Separator/>
    </StackPanel>
  </Grid>
</Window>
'@


$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$target = [Windows.Markup.XamlReader]::Load($reader)

$so.Window = $target

    @('First_Name','Last_Name','Street','City','Zip')| foreach-object {
      $name = $_
      $control = $target.FindName($name)
      if ($control -ne $null) {
        write-host ('Processing {0}' -f $control)
        $so.TextBox = $control
        $event = $control.Add_TextChanged
        $handler = {
          param(
            [object]$sender,
            [System.Windows.Controls.TextChangedEventArgs]$eventargs
          )
          $so.Result = $sender.Text
          # omitted: stash sender details into shared object
          write-host $so.Result
          write-host $sender.Name
        }
        # $hander is an System.Management.Automation.ScriptBlock
        # TODO: figure out how to clone
        $event.Invoke($handler)
      }
    }
    $target.ShowDialog() | Out-Null

это поделие перебирает тектбоксы и геренит новый кусок хендлера на каждый

YuS_2 17-09-2019 20:19 2888376

Цитата:

Цитата Charg
Можно ли как-то собрать все эти текстбоксы в кучу, применить на эту кучу параметр, а текстбоксы все эти параметры унаследовали бы? »

Не совсем понятен вопрос. Вы хотите редактировать форму через код powershell?
Лучше заниматься редактированием в Visual Studio...
Цитата:

Цитата Charg
Аналогичный вопрос к ивентам - нужно на каждый из этих текстбоксов применить мою функцию на ивент TextChanged »

А связку кода с формой... можно подсмотреть, например, здесь

Цитата:

Цитата Charg
И снова таки, как-то можно одним действием добавить обработку этого ивента на все текстбоксы? »

Для ответа необходимо больше информации, т.е. как минимум, надо видеть форму, функцию и более подробную формулировку того, что хочется получить.

Serguei Kouzmine 17-09-2019 23:29 2888389

@YuS_2 так показал же как приделывать. с properties так же точно

Charg 18-09-2019 08:42 2888419

YuS_2,
xaml
<Window x:Class="WPF_Inkass.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"
Title="Инкассация" Height="400" Width="500" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Grid ForceCursor="True" Width="auto">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" MinWidth="180"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid x:Name="GridBills" Height="auto" Width="auto" Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="Номинал" HorizontalContentAlignment="Center" Grid.Column="0" Background="AntiqueWhite"/>
<Label Content="Количество" HorizontalContentAlignment="Center" Grid.Column="1" Background="AntiqueWhite" BorderBrush="Transparent"/>
<Label Content="Итого" HorizontalContentAlignment="Center" Grid.Column="2" Background="AntiqueWhite"/>
<Label Content="1 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="1"/>
<Label Content="2 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="2"/>
<Label Content="5 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="3"/>
<Label Content="10 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="4"/>
<Label Content="20 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="5"/>
<Label Content="50 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="6"/>
<Label Content="100 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="7"/>
<Label Content="200 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="8"/>
<Label Content="500 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="9"/>
<Label Content="1000 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="10"/>
<TextBox Name="Bills1UAH_NumberTextbox" TabIndex="1" IsTabStop="True" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="1" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills2UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="2" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills5UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="3" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills10UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="4" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills20UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="5" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills50UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="6" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills100UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="7" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills200UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="8" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills500UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="9" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills1000UAH_NumberTextbox" BorderBrush="IndianRed" Grid.Column="1" Grid.Row="10" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
<TextBox Name="Bills1UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="1" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills2UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="2" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills5UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="3" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills10UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="4" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills20UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="5" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills50UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="6" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills100UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="7" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills200UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="8" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills500UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="9" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
<TextBox Name="Bills1000UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="10" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
</Grid>
<Grid x:Name="GridAdditionals" Height="auto" Width="auto" Grid.Column="1" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="Title0" Height="auto"/>
<RowDefinition x:Name="Date1" MinHeight="40" Height="auto"/>
<RowDefinition x:Name="Bag2" MinHeight="30" Height="auto"/>
<RowDefinition x:Name="Sender3" MinHeight="30" Height="auto"/>
<RowDefinition x:Name="Recipient4" MinHeight="30" Height="auto"/>
<RowDefinition x:Name="ResultSum5"/>
<RowDefinition x:Name="Button6"/>
<RowDefinition x:Name="Notes7" Height="auto"/>
</Grid.RowDefinitions>
<Label HorizontalContentAlignment="Center" Content="Доп. информация" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="AntiqueWhite"/>

<Label x:Name="InkassDateLabel" HorizontalContentAlignment="Right" Content="Дата инкассации" VerticalAlignment="Center" Grid.Row="1" Grid.Column="0"/>
<DatePicker Name="InkassDate" IsTodayHighlighted="True" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"/>

<Label x:Name="BagNumberLabel" HorizontalContentAlignment="Right" Content="Сумка №" VerticalAlignment="Center" Grid.Row="2" Grid.Column="0"/>
<TextBox BorderBrush="IndianRed" Name="BagNumberTextbox" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="1"/>

<Label x:Name="SenderLabel" HorizontalContentAlignment="Right" Content="Отправитель:" VerticalAlignment="Center" Grid.Row="3" Grid.Column="0"/>
<TextBox BorderBrush="IndianRed" Name="SenderTextbox" Text="ФОП " VerticalContentAlignment="Center" Grid.Row="3" Grid.Column="1"/>

<Label x:Name="RecipientLabel" HorizontalContentAlignment="Right" Content="Получатель:" VerticalAlignment="Center" Grid.Row="4" Grid.Column="0"/>
<TextBox BorderBrush="IndianRed" Name="RecipientTextbox" Text="ФОП " VerticalContentAlignment="Center" Grid.Row="4" Grid.Column="1"/>

<Label Name="ResultLabel" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Row="5" Grid.Column="0"/>
<TextBox Name="ResultTextbox" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Row="5" Grid.Column="1" IsTabStop="False" BorderBrush="Transparent" IsReadOnly="True" IsHitTestVisible="False"/>

<Button IsTabStop="False" IsEnabled="True" Name="FinalButton" Content="Сначала заполни всё красное" Grid.ColumnSpan="2" Grid.Row="6" Width="auto" Height="auto" BorderBrush="Black"/>
</Grid>
</Grid>
</Window>

posh (в текущем виде)
<#
To be able to export GUI made in Visual Studio into Powershell:

Change first XAML row
From: <Window x:Class="WPF_Inkass.MainWindow"
To: <Window

TODO: format automatically
#>


<########################
#### FUNCTIONS START ####
#########################>

function fValidate {
# todo
}

function fCalculateSumms {
# Bills
$Bills1UAH_ResultTextbox.Text = (1 * $($Bills1UAH_NumberTextbox.Text))
$Bills2UAH_ResultTextbox.Text = (2 * $($Bills2UAH_NumberTextbox.Text))
$Bills5UAH_ResultTextbox.Text = (5 * $($Bills5UAH_NumberTextbox.Text))
$Bills10UAH_ResultTextbox.Text = (10 * $($Bills10UAH_NumberTextbox.Text))
$Bills20UAH_ResultTextbox.Text = (20 * $($Bills20UAH_NumberTextbox.Text))
$Bills50UAH_ResultTextbox.Text = (50 * $($Bills50UAH_NumberTextbox.Text))
$Bills100UAH_ResultTextbox.Text = (100 * $($Bills100UAH_NumberTextbox.Text))
$Bills200UAH_ResultTextbox.Text = (200 * $($Bills200UAH_NumberTextbox.Text))
$Bills500UAH_ResultTextbox.Text = (500 * $($Bills500UAH_NumberTextbox.Text))
$Bills1000UAH_ResultTextbox.Text = (1000 * $($Bills1000UAH_NumberTextbox.Text))

# Overall Result
$overall = $(
[decimal]$($Bills1UAH_ResultTextbox.Text) +
[decimal]$($Bills2UAH_ResultTextbox.Text) +
[decimal]$($Bills5UAH_ResultTextbox.Text) +
[decimal]$($Bills10UAH_ResultTextbox.Text) +
[decimal]$($Bills20UAH_ResultTextbox.Text) +
[decimal]$($Bills50UAH_ResultTextbox.Text) +
[decimal]$($Bills100UAH_ResultTextbox.Text) +
[decimal]$($Bills200UAH_ResultTextbox.Text) +
[decimal]$($Bills500UAH_ResultTextbox.Text) +
[decimal]$($Bills1000UAH_ResultTextbox.Text)
)
$ResultLabel.Content = "Итоговая сумма:"
$ResultTextbox.Text = "$overall грн."
$ResultTextbox.Background = "LightGreen"
}

function fButtonClick {
fCalculateSumms
}

<########################
##### FUNCTIONS END #####
#########################
#### XAML GUI START #####
#########################>

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = @" форма "@

<########################
##### XAML GUI END ######
#########################>

# Read XAML
$reader = (New-Object System.Xml.XmlNodeReader $XAML)
try{
$Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
Write-Warning $_.Exception
throw
}

# Store Form Objects In PowerShell
$allnewelements = @()
$xaml.SelectNodes("//*[@Name]") | ForEach-Object {Set-Variable -Name ($_.Name) -Value $Form.FindName($_.Name); $allnewelements += $_}

# Make DatePicker select today's date by default
$InkassDate.SelectedDate = [datetime]::Now

$button = $Form.FindName("FinalButton")
$button.Add_Click({ fButtonClick })


# Show Form SHOULD BE LAST ROW
$Form.ShowDialog() | Out-Null

# Get date with ukrainian month name in genitive case
if ($null -ne $($InkassDate.Text)) {
[int]$MonthNumber = $InkassDate.Text | Get-Date -Format "MM"
$MonthName = ([cultureinfo]::CreateSpecificCulture("uk-UA")).DateTimeFormat.MonthGenitiveNames[$($MonthNumber - 1)]
$UkrainianDateText = $InkassDate.Text | Get-Date -Format "dd $($MonthName) yyyy"
}
else {
$InkassDate.SelectedDate = [datetime]::Now
}


Контекст - на магазине продавец заполняет количество купюр по номиналу, еще пару полей, жмёт кнопку и печатаются 3 бумажки для инкассации по шаблону, используя введённые данные.

Цитата:

Цитата YuS_2
Лучше заниматься редактированием в Visual Studio... »

Именно так я и делаю. Вот есть у меня 20 текстбоксов. И задал я для них свойство HorizontalContentAlignment="Center". А через 10 минут передумал и надо бы мне его убрать. На 20 текстбоксах вручную убирать? Работать то конечно будет, а если бы текстбоксов было 100? Вот для этого я и спрашивал о каком-нибудь механизм чтобы либо обернуть все текстбоксы во что-то и применить свойство единожды на родительский элемент или где-то рядом задать какой-нибудь шаблон стиля а потом применять к каждому текстбоксу использовать стиль такой-то. В общем механизм схожий с ID и class в CSS.
То же касается ивентов - каждый раз когда вводится что-то в колонку "количество" - сумма по этой банкноте и общая - должны пересчитываться, снова таки на каждый из 10 текстбоксов надо вручную дописать ивент.

Serguei Kouzmine, спасибо. Посмотрел, ничего не понял) Я пока что не понимаю как работают классы и что они вообще из себя представляют, поэтому эта часть кода для меня - черный ящик.
Буду пробовать методом тыка адаптировать под себя.

Iska 18-09-2019 10:05 2888435

Charg, у формы есть какое-нибудь встроенное свойство/метод .Controls, возвращающее коллекцию находящихся на ней элементов управления? Если да — возвращайте и перебирайте её элементы, проверяйте их тип, и если он будет TextBox (или как там) — меняйте его свойства на потребные.

Charg 18-09-2019 10:55 2888449

Цитата:

Цитата Iska
у формы есть какое-нибудь встроенное свойство/метод .Controls, возвращающее коллекцию находящихся на ней элементов управления? »

Не нашел.

Serguei Kouzmine 18-09-2019 12:08 2888456

ro@Charg
да поможет вам XML

Код:

$textbox_nodes = $xaml.SelectNodes('//*[contains(name(.) ,"TextBox")]')
$textbox_names = @()
$textbox_nodes | foreach-object {
  $textbox_node = $_
  if (($textbox_node.Attributes -ne $null) -and ($textbox_node.Attributes.GetNamedItem('x:Name') -ne $null )) {
    $name = $textbox_node.Attributes['x:Name'].'#text'
    if ($name -ne $null) {
      write-host ('Found DOM element attribute: {0} of {1} of namepace {2} ' -f $name, $textbox_node.getType(), $textbox_node.GetNamespaceOfPrefix('x'))
      $textbox_names += $name
    }
  }
}

write-host ('names: {0}' -f ( $textbox_names -join ','))
# @('First_Name','Last_Name','Street','City','State', 'Zip')

ну и

Код:

$textbox_names | foreach-object {

  $name = $_

  $control = $target.FindName($name)
  if ($control -ne $null) {
    write-host ('Adding event handler to {0} named {1}' -f $control.getType() , $control.Name)
    $control.Background = [System.Windows.Media.Brushes]::Aqua
..


Charg 18-09-2019 13:04 2888461

Serguei Kouzmine, а вот тут всё понятно, спасибо.

Serguei Kouzmine 18-09-2019 19:53 2888507

как говорится it was my pleasure, anytime ...
остальное ще проще но я бы на вашем добавил namespaces в Name аттрибуты чтобы рыло было в http://schemas.microsoft.com/winfx/2006/xaml
вместо http://schemas.microsoft.com/winfx/2...l/presentation

YuS_2 18-09-2019 23:13 2888527

Цитата:

Цитата Charg
На 20 текстбоксах вручную убирать? »

Ну, не в каждом по отдельности, но вручную...
Сгруппировать-то можно (например, в стекпанель), но не всеми свойствами в дочерних объектах можно манипулировать через родителя... т.е. размеры, например, вряд ли получится присваивать полям.
По шаблону - не знаю, возможно, что-то и существует, но не попадалось на глаза и не пользовался...
Скорее, можно осуществить желаемое, если выделить несколько элементов, а потом на панели свойств уже осуществлять очистку или изменение каких-либо свойств.

Цитата:

Цитата Charg
То же касается ивентов - каждый раз когда вводится что-то в колонку "количество" - сумма по этой банкноте и общая - должны пересчитываться, снова таки на каждый из 10 текстбоксов надо вручную дописать ивент. »

Ну, тут всё просто...
Группируем текстбоксы (в которых осуществляется ввод) в ту же StackPanel, присваиваем ей имя, например, Stack1.
Далее, меняем код создания переменных на такой:
Код:

$xaml.selectnodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | %{
        set-variable -name "WPF$($_.name)" -value $form.findname($_.name) -scope global
}

а также, можно добавить функцию, для просмотра созданных переменных:
Код:

function get-formvariables{
        write-host "found the following interactable elements from our form" -for cyan
        get-variable wpf*
}
get-formvariables

- здесь в обоих функциях, для создаваемых переменных, используется префикс WPF, для простоты получения списка созданных переменных. Т.е. в коде необходимо поменять имена переменных для формы.
Затем, можем запустить форму (. .\script.ps1) и посмотреть, что переменная $WPFStack1 существует.
Далее смотрим доступные методы:
Код:

$WPFStack1|gm add* -m method -force
и видим, что существует, например такой: add_KeyUp
Создаем обработчик ивента:
Код:

$WPFStack1.add_KeyUp({
        fButtonClick
})

и вуаля, получаем то, что требовалось с помощью одного обработчика.
Здесь полный код со всеми корректировками:
script.ps1
Код:

<#
To be able to export GUI made in Visual Studio into Powershell:

Change first XAML row
From: <Window x:Class="WPF_Inkass.MainWindow"
To: <Window

TODO: format automatically
#>


<########################
#### FUNCTIONS START ####
#########################>


function fValidate {
        # todo
}

function fCalculateSumms {
        # Bills
        $wpfBills1UAH_ResultTextbox.Text = (1 * $($wpfBills1UAH_NumberTextbox.Text))
        $wpfBills2UAH_ResultTextbox.Text = (2 * $($wpfBills2UAH_NumberTextbox.Text))
        $wpfBills5UAH_ResultTextbox.Text = (5 * $($wpfBills5UAH_NumberTextbox.Text))
        $wpfBills10UAH_ResultTextbox.Text = (10 * $($wpfBills10UAH_NumberTextbox.Text))
        $wpfBills20UAH_ResultTextbox.Text = (20 * $($wpfBills20UAH_NumberTextbox.Text))
        $wpfBills50UAH_ResultTextbox.Text = (50 * $($wpfBills50UAH_NumberTextbox.Text))
        $wpfBills100UAH_ResultTextbox.Text = (100 * $($wpfBills100UAH_NumberTextbox.Text))
        $wpfBills200UAH_ResultTextbox.Text = (200 * $($wpfBills200UAH_NumberTextbox.Text))
        $wpfBills500UAH_ResultTextbox.Text = (500 * $($wpfBills500UAH_NumberTextbox.Text))
        $wpfBills1000UAH_ResultTextbox.Text = (1000 * $($wpfBills1000UAH_NumberTextbox.Text))

        # Overall Result
        $overall = $(
                [decimal]$($wpfBills1UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills2UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills5UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills10UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills20UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills50UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills100UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills200UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills500UAH_ResultTextbox.Text) +
                [decimal]$($wpfBills1000UAH_ResultTextbox.Text)
        )
        $wpfResultLabel.Content = "Итоговая сумма:"
        $wpfResultTextbox.Text = "$overall грн."
        $wpfResultTextbox.Background = "LightGreen"
}

function fButtonClick {
        fCalculateSumms
}

<########################
##### FUNCTIONS END #####
#########################
#### XAML GUI START #####
#########################>

[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = @"
<Window
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"
Title="Инкассация" Height="400" Width="500" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
    <Grid ForceCursor="True" Width="auto">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="auto" MinWidth="180"/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Grid x:Name="GridBills" Height="auto" Width="auto" Grid.Column="0" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"></ColumnDefinition>
                <ColumnDefinition Width="auto"></ColumnDefinition>
                <ColumnDefinition Width="auto"></ColumnDefinition>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="auto"/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <Label Content="Номинал" HorizontalContentAlignment="Center" Grid.Column="0" Background="AntiqueWhite"/>
            <Label Content="Количество" HorizontalContentAlignment="Center" Grid.Column="1" Background="AntiqueWhite" BorderBrush="Transparent"/>
            <Label Content="Итого" HorizontalContentAlignment="Center" Grid.Column="2" Background="AntiqueWhite"/>
            <Label Content="1 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="1"/>
            <Label Content="2 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="2"/>
            <Label Content="5 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="3"/>
            <Label Content="10 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="4"/>
            <Label Content="20 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="5"/>
            <Label Content="50 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="6"/>
            <Label Content="100 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="7"/>
            <Label Content="200 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="8"/>
            <Label Content="500 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="9"/>
            <Label Content="1000 грн" Width="auto" Height="auto" VerticalAlignment="Center" HorizontalAlignment="Center" Grid.Column="0" Grid.Row="10"/>
            <StackPanel x:Name="Stack1" Grid.Column="1" Orientation="Vertical" Grid.Row="1" Grid.RowSpan="10">
                <TextBox x:Name="Bills1UAH_NumberTextbox" TabIndex="1" IsTabStop="True" BorderBrush="IndianRed" Width="auto" Height="34" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills2UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="35" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills5UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="34" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills10UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="35" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills20UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="34" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills50UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="35" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills100UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="34" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills200UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="35" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills500UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="34" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
                <TextBox x:Name="Bills1000UAH_NumberTextbox" BorderBrush="IndianRed" Width="auto" Height="35" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center"/>
            </StackPanel>
            <TextBox Name="Bills1UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="1" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills2UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="2" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills5UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="3" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills10UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="4" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills20UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="5" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills50UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="6" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills100UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="7" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills200UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="8" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills500UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="9" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
            <TextBox Name="Bills1000UAH_ResultTextbox" IsTabStop="False" Text="0" Grid.Column="2" Grid.Row="10" Width="auto" Height="auto" Margin="0,0,0,0" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsReadOnly ="True" BorderBrush="Transparent"/>
        </Grid>
        <Grid x:Name="GridAdditionals" Height="auto" Width="auto" Grid.Column="1" Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="auto"/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition x:Name="Title0" Height="auto"/>
                <RowDefinition x:Name="Date1" MinHeight="40" Height="auto"/>
                <RowDefinition x:Name="Bag2" MinHeight="30" Height="auto"/>
                <RowDefinition x:Name="Sender3" MinHeight="30" Height="auto"/>
                <RowDefinition x:Name="Recipient4" MinHeight="30" Height="auto"/>
                <RowDefinition x:Name="ResultSum5"/>
                <RowDefinition x:Name="Button6"/>
                <RowDefinition x:Name="Notes7" Height="auto"/>
            </Grid.RowDefinitions>
            <Label HorizontalContentAlignment="Center" Content="Доп. информация" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" Background="AntiqueWhite"/>

            <Label x:Name="InkassDateLabel" HorizontalContentAlignment="Right" Content="Дата инкассации" VerticalAlignment="Center" Grid.Row="1" Grid.Column="0"/>
            <DatePicker Name="InkassDate" IsTodayHighlighted="True" VerticalContentAlignment="Center" Grid.Row="1" Grid.Column="1"/>

            <Label x:Name="BagNumberLabel" HorizontalContentAlignment="Right" Content="Сумка №" VerticalAlignment="Center" Grid.Row="2" Grid.Column="0"/>
            <TextBox BorderBrush="IndianRed" Name="BagNumberTextbox" VerticalContentAlignment="Center" Grid.Row="2" Grid.Column="1"/>

            <Label x:Name="SenderLabel" HorizontalContentAlignment="Right" Content="Отправитель:" VerticalAlignment="Center" Grid.Row="3" Grid.Column="0"/>
            <TextBox BorderBrush="IndianRed" Name="SenderTextbox" Text="ФОП " VerticalContentAlignment="Center" Grid.Row="3" Grid.Column="1"/>

            <Label x:Name="RecipientLabel" HorizontalContentAlignment="Right" Content="Получатель:" VerticalAlignment="Center" Grid.Row="4" Grid.Column="0"/>
            <TextBox BorderBrush="IndianRed" Name="RecipientTextbox" Text="ФОП " VerticalContentAlignment="Center" Grid.Row="4" Grid.Column="1"/>

            <Label Name="ResultLabel" VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Row="5" Grid.Column="0"/>
            <TextBox Name="ResultTextbox" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Grid.Row="5" Grid.Column="1" IsTabStop="False" BorderBrush="Transparent" IsReadOnly="True" IsHitTestVisible="False"/>

            <Button IsTabStop="False" IsEnabled="True" Name="FinalButton" Content="Сначала заполни всё красное" Grid.ColumnSpan="2" Grid.Row="6" Width="auto" Height="auto" BorderBrush="Black"/>
        </Grid>
    </Grid>
</Window>
"@

<########################
##### XAML GUI END ######
#########################>

# Read XAML
$reader = (New-Object System.Xml.XmlNodeReader $XAML)
try{
        $Form=[Windows.Markup.XamlReader]::Load( $reader )
}
catch{
        Write-Warning $_.Exception
        throw
}

# Store Form Objects In PowerShell
#$allnewelements = @()
#$xaml.SelectNodes("//*[@Name]") | ForEach-Object {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name); $allnewelements += $_}

$xaml.selectnodes("//*[@*[contains(translate(name(.),'n','N'),'Name')]]") | %{
        set-variable -name "WPF$($_.name)" -value $form.findname($_.name) -scope global
}

function get-formvariables{
        write-host "found the following interactable elements from our form" -for cyan
        get-variable wpf*
}
get-formvariables

# Make DatePicker select today's date by default
$wpfInkassDate.SelectedDate = [datetime]::Now

$button = $Form.FindName("FinalButton")
$button.Add_Click({
        fButtonClick
})

$WPFStack1.add_KeyUp({
        fButtonClick
})

# Show Form SHOULD BE LAST ROW
$Form.ShowDialog() | Out-Null

# Get date with ukrainian month name in genitive case
if ($null -ne $($wpfInkassDate.Text)) {
        [int]$MonthNumber = $wpfInkassDate.Text | Get-Date -Format "MM"
        $MonthName = ([cultureinfo]::CreateSpecificCulture("uk-UA")).DateTimeFormat.MonthGenitiveNames[$($MonthNumber - 1)]
        $UkrainianDateText = $wpfInkassDate.Text | Get-Date -Format "dd $($MonthName) yyyy"
} else {
        $wpfInkassDate.SelectedDate = [datetime]::Now
}


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

Serguei Kouzmine 19-09-2019 05:38 2888541

@YuS_2 при всем уважении все это уже было в моем первом ответе. и использовать XML API чтобы резать по живому XAML есть моветон помоему

YuS_2 19-09-2019 06:00 2888545

Цитата:

Цитата Serguei Kouzmine
при всем уважении все это уже было в моем первом ответе. »

Вам не показалось, что после вашего ответа, последовало это:
Цитата:

Цитата Charg
спасибо. Посмотрел, ничего не понял) »

?
Так, что говорить о том, что всё это было - как раз, моветон. Тем более, что там даже намека на это не было, ни на описание, ни хотя бы комментарии к коду. Ясно же сказали:
Цитата:

Цитата Charg
Пробую WPF »

к тому же, я уже не говорю об этом:

-это то, что было в вашем первом ответе.
Цитата:

Цитата Serguei Kouzmine
и использовать XML API чтобы резать по живому XAML есть моветон помоему »

Чего-чего? :)
Попытайтесь пояснить, что такое "резать по живому XML API", а потом уже можем поговорить об этике и эстетике, да и о функциональности тоже...
:yes:

Serguei Kouzmine 20-09-2019 05:28 2888700

@YuS_2 извинтие если задело - непреднамеренно.

про код который есть и нет оч возм у меня его там на чердаке полный чемодан мог перепутать что и где..
API System.Windows.Controls в работе с UWP предпочтительнее System.Xml

YuS_2 20-09-2019 09:07 2888716

Цитата:

Цитата Serguei Kouzmine
извинтие если задело - непреднамеренно. »

не то, чтобы задело, просто не люблю таких комментов, в которых нет абсолютно никаких конкретностей, только общее замечание... мол, ваш код плохой и точка.
Вот, если бы было указание, что именно не так, тогда только рад буду чему-то научиться... а если ещё и предложение будет, как сделать лучше, это вообще идеальный комментарий.

А по сути вопроса:
В вашем коде, из первого ответа, чтобы не валились ошибки, добавление класса WPF лучше поместить перед объявлением синхронизированной хэштаблицы, т.к. внутри неё используется класс System.Windows.Window, который недоступен, без добавления WPF.
К тому же, у вас используется синхронизированная хэштаблица, инициализируется дополнительный ранспейс, но сам он не используется, для чего он, собственно и вписан в код, т.е. не происходит освобождение консоли для внешнего управления формой... но это дело третье.

Далее, что касается XML API, резать XAML... вот ваш код:
Цитата:

Цитата Serguei Kouzmine
$textbox_nodes = $xaml.SelectNodes('//*[contains(name(.) ,"TextBox")]') »

- как это называется? :)
По-хорошему, вместо всего этого, надо создавать полноценную связку MVVM, с классами, с определенной схемой работы и обработкой INotifyPropertyChanged, но в этом у меня познаний немного (так, простенькую форму можно накидать, а для чего-либо посложнее, надо будет изучать подробнее dotnet, сам WPF, да и XAML тоже), вот поэтому и не берусь...

Charg 20-09-2019 15:22 2888804

Цитата:

Цитата YuS_2
$xaml.SelectNodes('//*[contains(name(.) ,"TextBox")]') »

А где можно почитать про вот это вот? Синтаксис этого фильтра.

Iska 20-09-2019 16:06 2888807

Начать ознакомление можно прямо отсюда: XPath — Википедия, а затем копать вглыбь отсюда: XPath Reference | Microsoft Docs.


Время: 06:57.

Время: 06:57.
© OSzone.net 2001-