I'd like to find Button node within XAML in following PowerShell script. But I can't find it.
[xml]$xaml1 = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="400" Width="640">
<Button Content="Button" HorizontalAlignment="Left" Margin="99,20,0,0" VerticalAlignment="Top" Width="60" Height="30"/>
</Window>
'#
$xaml1.SelectNodes("//Button") | ForEach {
$_.Name
}
# No OUTOUT from above code!
When I delete line 3 and 4, it works.
[xml]$xaml2 = #'
<Window
Title="MainWindow" Height="400" Width="640">
<Button Content="Button" HorizontalAlignment="Left" Margin="99,20,0,0" VerticalAlignment="Top" Width="60" Height="30"/>
</Window>
'#
$xaml2.SelectNodes("//Button") | ForEach {
$_.Name
}
# OUTPUT of above code:
Button
How can I find node within XAML with SelectNodes?
I found solution by checking property of each node.The following code works fine.
$xaml.SelectNodes("//*") | ? {$_.LocalName -eq "Button"} | % {
# action for each Button Node
}
The following is sample code using above.
[xml]$xaml = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="300" Width="300">
<StackPanel>
<Button x:Name="button0" Content="Button0"/>
<Button x:Name="button1" Content="Button1"/>
<Button x:Name="button2" Content="Button2"/>
<Button x:Name="button3" Content="Button3"/>
<Button x:Name="button4" Content="Button4"/>
<Button x:Name="button5" Content="Button5"/>
<ScrollViewer x:Name="scrollViewer" Height="150">
<TextBlock x:Name="msg" TextWrapping="Wrap"/>
</ScrollViewer>
</StackPanel>
</Window>
'#
$reader = New-Object System.Xml.XmlNodeReader $xaml
$frm = [System.Windows.Markup.XamlReader]::Load($reader)
$scrollViewer = $frm.FindName("scrollViewer")
$msg = $frm.FindName("msg")
$xaml.SelectNodes("//*") | ? {$_.LocalName -eq "Button"} | % {
$button = $frm.FindName($_.Name)
$button.add_Click({
$msg.Inlines.add($this.Content + " pushed`n")
$scrollViewer.ScrollToBottom()
})
}
$result = $frm.ShowDialog()
I'm sorry the followings are code:
[xml]$xaml1 = #'
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Title="MainWindow" Height="400" Width="640">
<Button Content="Button" HorizontalAlignment="Left" Margin="99,20,0,0" VerticalAlignment="Top" Width="60" Height="30"/>
</Window>
'#
[System.Xml.XmlNamespaceManager] $nsmgr = $xaml1.NameTable;
$nsmgr.AddNamespace($null, 'http://schemas.microsoft.com/winfx/2006/xaml/presentation');
$xaml1.SelectSingleNode("//Button", $nsmgr)
Try this:
$xaml1.Window.Button
$xaml.SelectNodes("//*[#Name]") | ForEach-Object {Set-Variable -Name ($.Name) -Value $Form.FindName($.Name)}
Now you have the Controls as Variable...
if the Name of a Button is "button" you have a variable $button in Powershell.
add a click like this then...
$button.add_click({write-host "clicked!!"})
Related
I am trying to display a text on a custome user control. I want that text to be passed via a mainview
this is the code I have:
MainView.axaml
<cc:Slot Grid.Row="0" Grid.Column="1" Dot="Number one"/>
<cc:Slot Grid.Row="0" Grid.Column="2" Dot="Number two"/>
This is my custom user control:
Slot.axaml
<UserControl xmlns="https://github.com/avaloniaui"
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:controls="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:cc="clr-namespace:Diagnostica.CustomControls;assembly=Diagnostica.CustomControls"
x:Class="Diagnostica.CustomControls.OmniSlot">
<Button>
<TextBlock Text="{Binding Dot}"/>
</Button>
</Grid>
</Button>
</UserControl>
and its .cs file"
Slot.axaml.cs
public string Dot
{
get => GetValue(DotProperty);
set => SetValue(DotProperty, value);
}
public static readonly StyledProperty<string> DotProperty =
AvaloniaProperty.Register<Slot, string>(nameof(Dot), defaultValue: "Black");
what i get like this is a disabled box. How can this get fixed?
View:
<Rectangle Stroke="{TemplateBinding DotColor}" StrokeThickness="2" Width="20" Height="20" Fill="{TemplateBinding DotColorBrush}" VerticalAlignment="Top" HorizontalAlignment="Right"/>
ViewModel:
public static readonly StyledProperty<string> DotColorProperty = AvaloniaProperty.Register<OmniSlotControl, string>(nameof(DotColor), "Red");
public string DotColor
{
get => GetValue(DotColorProperty);
set
{
SetValue(DotColorProperty, value);
DotColorBrush = Avalonia.Media.Brush.Parse(value);
}
}
The goal I'm trying to accomplish here is to change the NavigationView Header property when I press a NavigationView MenuItem, where it switches to a different page. I want the header to display the text on the button that was pressed but I'm very much learning to use the WinUI/XAML library still and looking at the gallery and documentation isn't really helping.
NavigationView.MenuItems on MainPage.xaml
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem Icon="Home" Content="Home" x:Name="Menu1Item" Tag="Page1"/>
<muxc:NavigationViewItem Icon="Contact" Content="Account" x:Name="Menu2Item" Tag="Page2"/>
<muxc:NavigationViewItem Icon="Bullets" Content="Attendance" x:Name="Menu3Item" Tag="Page3"/>
<muxc:NavigationViewItem Icon="Library" Content="Grades" x:Name="Menu4Item" Tag="Page4"/>
<muxc:NavigationViewItem Icon="Flag" Content="Grad Reqs" x:Name="Menu5Item" Tag="Page5"/>
</muxc:NavigationView.MenuItems>
https://i.stack.imgur.com/ZeNdf.png
https://i.stack.imgur.com/t7eEj.png
EDIT:
MainPage.xaml:
<Page
xmlns:muxc="using:Microsoft.UI.Xaml.Controls"
x:Class="ProjectHurricanes.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:ProjectHurricanes"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
muxc:BackdropMaterial.ApplyToRootOrPageBackground="True"
>
<Page.Resources>
<!--This top margin is the height of the custom TitleBar-->
<Thickness x:Key="NavigationViewContentMargin">0,48,0,0</Thickness>
</Page.Resources>
<Grid>
<Border x:Name="AppTitleBar"
IsHitTestVisible="True"
VerticalAlignment="Top"
Background="Transparent"
Height="40"
Canvas.ZIndex="1"
Margin="48,8,0,0">
<StackPanel Orientation="Horizontal">
<Image x:Name="AppFontIcon"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Source="Assets/Square44x44Logo.png"
Width="16"
Height="16"/>
<TextBlock x:Name="AppTitle"
Text="Project"
VerticalAlignment="Center"
Margin="12, 0, 0, 0"
Style="{StaticResource CaptionTextBlockStyle}" />
</StackPanel>
</Border>
<muxc:NavigationView x:Name="NavigationViewControl"
IsTitleBarAutoPaddingEnabled="False"
IsBackButtonVisible="Visible"
Header="Home"
DisplayModeChanged="NavigationViewControl_DisplayModeChanged"
SelectionFollowsFocus="Enabled"
ItemInvoked="NavigationView_ItemInvoked"
PaneDisplayMode="Left"
Canvas.ZIndex="0">
<muxc:NavigationView.MenuItems>
<muxc:NavigationViewItem Icon="Home" Content="Home" x:Name="Menu1Item" Tag="Page1"/>
<muxc:NavigationViewItem Icon="Contact" Content="Account" x:Name="Menu2Item" Tag="Page2"/>
<muxc:NavigationViewItem Icon="Bullets" Content="Attendance" x:Name="Menu3Item" Tag="Page3"/>
<muxc:NavigationViewItem Icon="Library" Content="Grades" x:Name="Menu4Item" Tag="Page4"/>
<muxc:NavigationViewItem Icon="Flag" Content="Grad Reqs" x:Name="Menu5Item" Tag="Page5"/>
</muxc:NavigationView.MenuItems>
<Grid Padding="20">
<Frame x:Name="rootFrame"/>
</Grid>
</muxc:NavigationView>
</Grid>
</Page>
MainPage.xaml.cs:
OnItemInvoked:
private void NavigationView_OnItemInvoked(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs args)
{
FrameNavigationOptions navOptions = new FrameNavigationOptions();
navOptions.TransitionInfoOverride = args.RecommendedNavigationTransitionInfo;
#pragma warning disable IDE0007 // Use implicit type
string navItemTag = args.InvokedItemContainer.Tag.ToString();
#pragma warning restore IDE0007 // Use implicit type
Type pageType = null;
if (navItemTag == "Page1")
{
pageType = typeof(Page1);
}
else if (navItemTag == "Page2")
{
pageType = typeof(Page2);
}
else if (navItemTag == "Page3")
{
pageType = typeof(Page3);
}
else if (navItemTag == "Page4")
{
pageType = typeof(Page4);
}
else if (navItemTag == "Page5")
{
pageType = typeof(Page5);
}
if (pageType == null)
{
return;
}
rootFrame.NavigateToType(pageType, null, navOptions);
}
You can add the ItemInvoked event to your NavigationView and in the event you can simple get the Content of the selected item.
An using-directive to muxc
using muxc = Microsoft.UI.Xaml.Controls;
The event in your MainPage.xaml.cs
private void NavigationView_ItemInvoked(Microsoft.UI.Xaml.Controls.NavigationView sender, Microsoft.UI.Xaml.Controls.NavigationViewItemInvokedEventArgs args)
{
if (NavigationView.SelectedItem is muxc.NavigationViewItem item)
{
sender.Header = item.Content.ToString();
}
}
The event added to your NavigationView
<muxc:NavigationView ItemInvoked="NavigationView_ItemInvoked" x:Name="NavigationView">
How do you stop a ScrollViewer's scrollbar from overlapping content like this?
I have a RichTextBlock containing text and no matter how wide I make the RichTextBlock, or how I change the Margin and Padding values, I cannot get the scrollbar to move further to the right to stop this overlap from happening. I'm running Windows 10 and it is configured to hide scrollbars until the mouse pointer hovers over them.
Below is the XAML for my app.
<Page
x:Class="PaulWinPOS1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:PaulWinPOS1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid Margin="0,26,0,0">
<Button x:Name="butConnect" Content="Connect" Margin="0,38,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Click="ButConnect_Click" Width="92"/>
<Button x:Name="butLogin" Content="Login" Margin="0,92,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Width="92" IsEnabled="False" Click="ButLogin_Click"/>
<Button x:Name="butAdd" Content="Add Item" Margin="0,143,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Width="92" IsEnabled="False" Click="ButAdd_Click"/>
<ScrollViewer x:Name="scrollViewerWeb"
HorizontalScrollBarVisibility="Auto"
VerticalScrollBarVisibility="Auto"
HorizontalAlignment="Left"
Width="350"
Padding="16,0"
Grid.RowSpan="10"
FontFamily="Segoe UI" RequestedTheme="Dark" ZoomMode="Enabled"
Margin="669,304,0,0" >
<WebView x:Name="webviewReceipt"
Margin="10,10,50,10"
HorizontalAlignment="Left"
Height="333" Width="300"
VerticalAlignment="Top"
ScrollViewer.VerticalScrollMode="Enabled"
ScrollViewer.VerticalScrollBarVisibility="Visible" />
</ScrollViewer>
<Button x:Name="butDisconnect" Content="Disconnect" Margin="0,244,48,0" VerticalAlignment="Top" RenderTransformOrigin="-3.274,0.344" HorizontalAlignment="Right" Height="32" Width="92" Click="ButDisconnect_Click"/>
</Grid>
</Page>
The scroll bar of WebView is special and cannot be solved by the conventional ScrollViewer additional properties, but the scroll bar of the WebView can be disabled through the CSS of the web page.
body {
-ms-overflow-style: none;
}
If you cannot modify the source code of the webpage, you can perform the following operations after the WebView content is loaded:
private async void webviewReceipt_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
string js = "var style = document.createElement('style');" +
"style.type = 'text/css';" +
"style.innerHTML = \"body{ -ms-overflow-style: none !important; }\";" +
"document.getElementsByTagName('Head').item(0).appendChild(style); ";
await webviewReceipt.InvokeScriptAsync("eval", new string[] { js });
}
Update
If we need to display a scroll bar, we can add a padding-right to the body so that the scroll bar does not block the content.
private async void webviewReceipt_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
string js = "var style = document.createElement('style');" +
"style.type = 'text/css';" +
"style.innerHTML = \"body{ padding-right: 24px; }\";" +
"document.getElementsByTagName('Head').item(0).appendChild(style); ";
await webviewReceipt.InvokeScriptAsync("eval", new string[] { js });
}
You need to add a Padding to ScrollViewer.
<ScrollViewer Padding="18, 0">
<RichTextBlock />
</ScrollViewer>
Usually the ScrollBar Width is 18.
It looks like you have the scroll bars enabled on both the web view and scroll viewer. You can try disabling the scroll bars on one of them to see if it makes a difference.
I am working on my first form in Powershell and am using XAML (built on the code from https://foxdeploy.com/2015/04/10/part-i-creating-powershell-guis-in-minutes-using-visual-studio-a-new-hope/).
The form works great so now I'm working on data validation. I am trying to make all of the fields mandatory through a While loop, but I can't break out of it. How would I take the code below and make it understand when someone clicks the Cancel button, that it should exit the loop? I tried checking $WPFcancelButton.IsPressed, but that doesn't seem to be getting updated.
Thanks.
Function Get-HubNameFields {
$inputXML = #"
<Window x:Class="WpfApplication1.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:WpfApplication1"
mc:Ignorable="d"
Title="Naming Tool" Height="350" Width="525">
<Grid Margin="0,0,-8,0" HorizontalAlignment="Left" Width="525">
<TextBlock x:Name="textBlock" Margin="10,10,145.907,0" TextWrapping="Wrap" Text="Define the parameters of a name" VerticalAlignment="Top" Height="17.945"/>
<Label x:Name="custLongNameLabel" Content="Customer Long Name" HorizontalAlignment="Left" Margin="10,32.945,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="custLongNameTxt" Height="21.96" Margin="141.003,36.945,224.239,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip="Full name of the customer."/>
<Label x:Name="custShortNameLabel" Content="Customer Short Name" HorizontalAlignment="Left" Margin="10,59.905,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="custShortNameTxt" Height="21.96" Margin="141.003,63.905,224.239,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip="Abreviation of the customer's name."/>
<Label x:Name="siteLongNameLabel" Content="Site Long Name" HorizontalAlignment="Left" Margin="10,86.865,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="siteLongNameTxt" Height="21.96" Margin="141.003,90.865,224.239,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip="Full name of the site."/>
<Label x:Name="siteShortNameLabel" Content="Site Short Name" HorizontalAlignment="Left" Margin="10,113.785,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="siteShortNameTxt" Height="21.96" Margin="141.003,117.825,224.239,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip="Abbreviation of the site's name."/>
<Label x:Name="hubNumberLabel" Content="Hub Number" HorizontalAlignment="Left" Margin="10,140.825,0,0" VerticalAlignment="Top"/>
<TextBox x:Name="hubNumberTxt" Height="21.96" Margin="141.003,144.785,224.239,0" TextWrapping="Wrap" VerticalAlignment="Top" ToolTip="Number of the Hub."/>
<RadioButton x:Name="radioButton" Content="Data Center Hub" HorizontalAlignment="Left" Margin="10,0,0,122.611" VerticalAlignment="Bottom"/>
<RadioButton x:Name="radioButton1" Content="Office/Other" HorizontalAlignment="Left" Margin="10,0,0,102.651" VerticalAlignment="Bottom"/>
<Button x:Name="okButton" Content="OK" HorizontalAlignment="Left" Margin="18.928,0,0,10" VerticalAlignment="Bottom" Width="50" IsDefault="True"/>
<Button x:Name="cancelButton" Content="Cancel" HorizontalAlignment="Left" Margin="80.317,0,0,10" VerticalAlignment="Bottom" Width="50" IsCancel="True"/>
</Grid>
</Window>
"#
$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N' -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('PresentationFramework')
[xml]$XAML = $inputXML
#Read XAML
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
Try {
$form = [Windows.Markup.XamlReader]::Load($reader)
}
Catch {
Write-Host "Unable to load Windows.Markup.XamlReader. Double-check syntax and ensure .Net is installed."
}
#This line takes the XAML data, adds "WPF" to the front of each XML node name, and creates a global variable.
$xaml.SelectNodes("//*[#Name]") | Foreach {Set-Variable -Name "WPF$($_.Name)" -Value $Form.FindName($_.Name) -Scope Global}
<#Only need this function and its call if you don't know the name of the variables that the function generates from the XML.
Function Get-FormVariables {
If ($global:ReadmeDisplay -ne $true) {
Write-host "If you need to reference this display again, run Get-FormVariables" -ForegroundColor Yellow;$global:ReadmeDisplay=$true
}
Write-host "Found the following interactable elements from our form" -ForegroundColor Cyan
Get-Variable WPF*
}
Get-FormVariables#>
#Specify what the OK button should do, when clicked.
$WPFokButton.Add_Click({$form.Close()})
#Now that the form is built, show it, surpressing other messages.
$form.ShowDialog() | Out-Null
}
#Initialize some local variables.
$hubType = $null
$TextInfo = (Get-Culture).TextInfo
While ((($customerLongName.Length -eq 0) -or ($customerShortName.Length -eq 0) -or ($siteLongName.Length -eq 0) -or ($siteShortName.Length -eq 0) -or ($hubType -eq $null)) -or ($WPFcancelButton.IsPressed -like "false*")) {
Write-Host "the cancel button value is $($WPFcancelButton.ispressed)"
Get-HubNameFields
$customerLongName = $WPFcustLongNameTxt.Text
$customerLongName = $TextInfo.ToTitleCase($customerLongName.ToLower())
$customerLongName = $customerLongName -replace '\s',''
$customerShortName = ($WPFcustShortNameTxt.Text).ToLower()
$customerShortName = $customerShortName -replace '\s',''
$siteLongName = $WPFsiteLongNameTxt.Text
$siteLongName = $TextInfo.ToTitleCase($siteLongName.ToLower())
$siteLongName = $siteLongName -replace '\s',''
$siteShortName = ($WPFsiteShortNameTxt.Text).ToLower()
$siteShortName = $siteShortName -replace '\s',''
If ($WPFradioButton.IsChecked -eq $true) {
$hubType = 'dh'
}
If ($WPFradioButton1.IsChecked -eq $true) {
$hubType = 'ch'
}
}
I added an event handler, to set a variable, and broke the loop based on that.
$WPFcancelButton.Add_Click({Set-Variable -Name UserCancelled -Value $true -Scope Global})
I am using Listbox and it contains button ,and i want to handle button click event using command.but my command never calls.
is this Correct way??
<pmControls:pmListBox Grid.Row="1" Margin="3" ItemsSource="{Binding Countries}" SelectedItem="{Binding SelectedCountry}" >
<pmControls:pmListBox.ItemTemplate >
<DataTemplate >
<Button Command="{Binding GetAllStatesCommand}" CommandParameter="{Binding}" Margin="3" Width="100" Height="50" Content="{Binding Title}">
</Button>
</DataTemplate>
</pmControls:pmListBox.ItemTemplate>
</pmControls:pmListBox>
The DataContext of one list item is different from the DataContextof the surrounding control. To bind that command to the DataContext of that control you have two options:
Either you provide the control with a name and reference to that:
<pmControls:pmListBox x:Name="myCoolListBox" [...]>
<pmControls:pmListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding DataContext.GetAllStatesCommand, ElementName=myCoolListBox}" CommandParameter="{Binding}" [...] />
</DataTemplate>
</pmControls:pmListBox.ItemTemplate>
</pmControls:pmListBox>
Or you create class holding your DataContext...
public class DataContextBinder : DependencyObject
{
public static readonly DependencyProperty ContextProperty = DependencyProperty.Register("Context", typeof(object), typeof(DataContextBinder), new PropertyMetadata(null));
public object Context
{
get { return GetValue(ContextProperty); }
set { SetValue(ContextProperty, value); }
}
}
...and create an instance of that in the resources section of your ListBox:
<pmControls:pmListBox x:Name="myCoolListBox" [...]>
<pmControls:pmListBox.Resources>
<local:DataContextBinder x:Key="dataContextBinder" Context="{Binding}" />
</pmControls:pmListBox.Resources>
<pmControls:pmListBox.ItemTemplate>
<DataTemplate>
<Button Command="{Binding Context.GetAllStatesCommand, Source={StaticResource dataContextBinder}" CommandParameter="{Binding}" [...] />
</DataTemplate>
</pmControls:pmListBox.ItemTemplate>
</pmControls:pmListBox>