I'm writing a PS Gui where a listview is present. The CSV contains two columns, hostname for simply identifying and the associated ip-address of the host.
I'm having the problem, that the listview is importing the hostname or the address from the csv, depending on how the import-csv command looks like. If I change the $.Adresse to $.Server, the output of the listview looks like in the screenshot. Both columns are filled with the same info, with the hostname or with the addresses. The columns are the same for the csv and the xaml file.
Import-CSV "C:\temp\verwaltungstool.csv" | ForEach-Object {$var_ServerListe.Items.Add($_.Server)}
Now I would like to either keep both columns in the listview and by clicking on the address to recall a function. How can I tell PS to import both columns in the same way as it would look like without a gui, with format-table?
As an alternative I would like to "link" the hostname with the ip-address so that an Invoke-Command could work with that as the hostnames aren't resolvable.
The CSV looks like this:
Server,Adresse
TS1,192.168.x.x
The Xaml looks like this:
<Window x:Class="test.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:test"
mc:Ignorable="d"
Title="Serverfalter" Height="500" Width="710">
<Grid x:Name="Rückhand" Background="#FF323232" Cursor="Arrow" Focusable="True" AllowDrop="True" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label x:Name="Version" Content="Version 0.3.2" HorizontalAlignment="Left" Margin="318,440,0,0" VerticalAlignment="Top" Width="70" FontSize="10" Foreground="White" Height="23"/>
<ListView x:Name="ServerListe" HorizontalAlignment="Left" Height="153" Margin="20,64,0,0" VerticalAlignment="Top" Width="370" Background="#FF646464" FontFamily="Bahnschrift" FontSize="14" Foreground="Black" BorderBrush="#FF828790" Visibility="Visible" RenderTransformOrigin="1,1">
<ListView.View>
<GridView>
<GridViewColumn Header="Server" Width="213"/>
<GridViewColumn Header="Adresse" Width="130"/>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="Button1" Content="Serverliste importieren" HorizontalAlignment="Left" Margin="20,27,0,0" VerticalAlignment="Top" FontFamily="Bahnschrift" Background="#FF5A5A5A" Foreground="White" FontSize="14"/>
</Grid>
</Window>
GUI
Related
I've created UserControl for adding/removing attributes using the buttons. It has ItemsControl with ObservableCollection of attributes bound to it as a ViewModel and button for adding new attribute to collection. Each new attribute creates an entity in collection which is also a UserControl with bound attribute ViewModel and button for deleting itself.
I wanted to write this functionality so the single attribute control (and other controls) can be reusable - and I use it in a few places. Currently adding new attributes works properly, but I can't find any working way for delete button to work properly and remove object from the collection.
I tried to refer through this.Parent, but CustomAttributeControl's parent is null, I tried to refer through Tag or use Prism.Core, but I couldn't implement anything properly for this to work and I couldn't find anyone with similar nested controls problem to base on. It's easy when there is no nested control for single attribute, but here I can't come up with anything. I'm fairly new to WPF and I feel there should be an easy way to do this.
single attribute control
attribute control's XAML:
<UserControl x:Class="xxx.UI.CustomAttributeControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:models="clr-namespace:xxx.ViewModels.Attributes"
mc:Ignorable="d" >
<DockPanel Width="auto" HorizontalAlignment="Stretch" Margin="0,2">
<TextBox Text="{Binding Name}" Height="20" TextWrapping="Wrap" Width="160"/>
<TextBlock Width="60"/>
<ComboBox x:Name="DataType" Height="20" Width="120" SelectionChanged="DataType_SelectionChanged"/>
<TextBlock Width="10"/>
<TextBox Text="{Binding ListValues}" x:Name="ListValues" Height="20" TextWrapping="Wrap" Width="120"/>
<DockPanel HorizontalAlignment="Right">
<CheckBox IsChecked="{Binding Visible}" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="20,0"/>
<Button x:Name="Delete" Content="X" Width="22" Height="20" VerticalAlignment="Center" HorizontalAlignment="Right" Margin="20,0"/>
</DockPanel>
</DockPanel>
</UserControl>
list control
list control's XAML:
<UserControl x:Class="xxx.UI.CustomAttributesControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:xxx.UI"
mc:Ignorable="d">
<StackPanel>
<Label FontSize="20">Custom attributes</Label>
<StackPanel>
<DockPanel HorizontalAlignment="Stretch">
<Label Width="160" HorizontalAlignment="Left" HorizontalContentAlignment="Center">Attribute name</Label>
<TextBlock Width="60"/>
<Label Width="120" HorizontalAlignment="Left" HorizontalContentAlignment="Center">Attribute type</Label>
<TextBlock Width="10"/>
<Label Width="120" HorizontalAlignment="Left" HorizontalContentAlignment="Center">List values</Label>
<DockPanel HorizontalAlignment="Right">
<Label Width="60" HorizontalAlignment="Right" HorizontalContentAlignment="Center">Visible</Label>
<Label Width="60" HorizontalAlignment="Right" HorizontalContentAlignment="Center">Delete</Label>
</DockPanel>
</DockPanel>
<ItemsControl ItemsSource="{Binding}"> <!-- it's binding ObservableCollection of custom attributes from parent control -->
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:CustomAttributeControl />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<DockPanel HorizontalAlignment="Right">
<Button Margin="20,10" Click="AddAttribute">+ Add attribute</Button>
</DockPanel>
</StackPanel>
</StackPanel>
</UserControl>
Code for adding attribute in .xaml.cs:
private void AddAttribute(object sender, RoutedEventArgs e)
{
var attributes = (ObservableCollection<CustomAttribute>)DataContext;
attributes.Add(new CustomAttribute());
}
So I have recently started learning more C# and I am currently trying to create a GUI. I so far have a title and a text box that looks like this:
https://i.imgur.com/BvpkQ3U.png
Yes, this looks fine, it's not the problem. The problem is when you open the window (by debugging it) the window is set to the size of which it looks like on the preview. Which is fine. But, when I maximize it the objects inside of the window do not get larger. They stay at the same size. Which looks like this:
BEFORE:
https://i.imgur.com/NuGTDwf.png
AFTER:
https://i.imgur.com/pVy2aYk.png
How can I make it so the objects inside of the window get larger just like the window itself does?
MainWindow.xaml:
<Window x:Name="THE_GUI" x:Class="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:GUI"
mc:Ignorable="d"
Title="GUI" Height="450" Width="800" Foreground="Black" WindowStyle="SingleBorderWindow">
<Grid>
<TextBlock x:Name="GUI_TITLE2" HorizontalAlignment="Center" Margin="0,10,0,0" Text="TITLE" TextWrapping="Wrap" VerticalAlignment="Top" Height="50" Width="125" FontSize="18"/>
<TextBox HorizontalAlignment="Left" Margin="41,35,0,0" Text="TextBox" TextWrapping="Wrap" VerticalAlignment="Top" Width="204" Height="375" IsReadOnly="True"/>
</Grid>
</Window>
If you require more code I can provide it
Thanks! :)
PS
I did see this question: WPF: How can I have controls in a grid automatically resize when the grid is resized? but it doesn't help me at all.
Do not set Height & Width of controls (TextBlock/TextBox) if you want them to resize. Also you are using a plain grid with no Row/Columns so WPF will not know how to scale your GUI.
You need to read about different type of Panels/Containers available in WPF and how to use them to Lay your Controls.
Check: StackPanel, WrapPanel, DockPanel. For Grid read about RowDefinitions and Columndefinitions. Read the WildCard height and width assignment.
As suggested by Prateek also, simply putting controls under grid won't work. If you want to go with grid control, then please have row and columns created to align the controls. I've updated your code and here it is:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="13*"/>
<RowDefinition Height="87*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="20*"/>
<ColumnDefinition Width="30*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1"
x:Name="GUI_TITLE2" HorizontalAlignment="Stretch"
Text="TITLE" TextWrapping="Wrap" VerticalAlignment="Stretch"
FontSize="18"/>
<TextBox Grid.Row="1" Grid.Column="0"
HorizontalAlignment="Stretch" Text="TextBox" TextWrapping="Wrap"
VerticalAlignment="Stretch" IsReadOnly="True"/>
</Grid>
I am creating a PowerShell gui that I am using to remove computers from Active Directory.
I was able to get the list view to populate the computer name, OU path, and IP address.
However when I am creating the script to delete the object, I am running into an issue.
I would like the user to be able to select the computer object from the list view and press delete.
However using SelectedItems grabs all 3 properties (Name, OU path, and IP address).
Output being:
#{Name=COMPUTER; DistinguishedName=CN=xx,OU=xx,OU=xx,OU=xx,OU=xx,OU=xx,DC=xx,DC=xx,DC=xx; IPv4Address=xx.xx.xx.xx}
How would I have it so that SelectedItems will only grab the computer name so I can pass it into a variable that can be used with Remove-ADComputer?
I apologize for any formatting issues. I am very new at this.
XML:
<Window x:Class="SCCMAD.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:SCCMAD"
mc:Ignorable="d"
Title="SCCMAD" Height="353.176" Width="586.987">
<Grid Margin="0,0,2,-31" HorizontalAlignment="Right" Width="577" Height="353" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBox x:Name="Input" HorizontalAlignment="Left" Height="23" Margin="50,86,129,0" TextWrapping="Wrap" Text="Type Device Name here..." VerticalAlignment="Top" Width="398" Grid.ColumnSpan="2" RenderTransformOrigin="0.501,0.522"/>
<Label x:Name="secondTitle" Content="Tool used for removal of devices from SCCM and/or AD" HorizontalAlignment="Left" Margin="130,34,0,0" VerticalAlignment="Top" Grid.ColumnSpan="2" Width="324" FontWeight="Bold"/>
<ListView x:Name="Grid" Margin="49,114,46,133" Grid.ColumnSpan="2">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding ="{Binding Name}" Width="120"/>
<GridViewColumn Header="Distinguished Name" DisplayMemberBinding ="{Binding DistinguishedName}" Width="120"/>
<GridViewColumn Header="IP Address" DisplayMemberBinding ="{Binding IPv4Address}" Width="120"/>
</GridView>
</ListView.View>
</ListView>
<Button x:Name="OK" Content="OK" Grid.Column="1" HorizontalAlignment="Left" Margin="163,86,0,0" VerticalAlignment="Top" Width="79" Height="23"/>
<Button x:Name="SCCM" Content="SCCM" HorizontalAlignment="Left" Margin="130,256,0,0" VerticalAlignment="Top" Width="75"/>
<Button x:Name="Both" Grid.ColumnSpan="2" Content="Both" HorizontalAlignment="Left" Margin="254,256,0,0" VerticalAlignment="Top" Width="75"/>
<Button x:Name="AD" Content="AD" HorizontalAlignment="Left" VerticalAlignment="Top" Width="75" Grid.Column="1" Margin="89,256,0,0"/>
<Label Content="Remove from:" HorizontalAlignment="Left" Margin="242,225,0,0" VerticalAlignment="Top" Width="95" Grid.ColumnSpan="2" FontWeight="Bold"/>
<StatusBar x:Name="StatusBar" HorizontalAlignment="Left" Height="30" Margin="0,290,0,0" VerticalAlignment="Top" Width="577" Grid.ColumnSpan="2"/>
</Grid>
</Window>
Powershell:
Function Get-ADDevice {
param($computername =$env:COMPUTERNAME)
Get-ADComputer -Filter "name -like '$computername*'" -Properties Name, DistinguishedName, IPv4Address | Select-Object Name, DistinguishedName, IPv4Address
}
$WPFOK.Add_Click({
try
{
$WPFGrid.Clear()
Get-ADDevice -computername $WPFInput.Text | % {$WPFGrid.AddChild($_)}
}
catch
{
$WPFStatusBar.Text = $_.Exception.Message
}
})
$WPFAD.Add_Click({
foreach($item in $WPFGrid.SelectedItems)
{
Write-Host $item
}
})
I define my own control - NameInfoControl, which are based on UserControl thorough XAML:
<UserControl x:Class="AcadLoadManager.NameInfoControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ToolBar>
<Button x:Name="btnAdd" x:FieldModifier="public" ToolTip="Add record" >
<Image Source="/AcadLoadManager;component/Icons/bullet_sparkle.png" Width="16"/>
</Button>
<Button x:Name="btnEdit" x:FieldModifier="public" ToolTip="Edit record">
<Image Source="/AcadLoadManager;component/Icons/bullet_edit.png" Width="16"/>
</Button>
<Button x:Name="btnRemove" x:FieldModifier="public" ToolTip="Remove record">
<Image Source="/AcadLoadManager;component/Icons/bullet_cross.png" Width="16"/>
</Button>
</ToolBar>
<ListView x:Name="myListView" x:FieldModifier="public" Margin="3" Grid.Row="1">
<ListView.View>
<GridView>
<GridViewColumn Width="100" Header="Global name"
DisplayMemberBinding="{Binding GlobalName}"/>
<GridViewColumn Width="100" Header="Local name"
DisplayMemberBinding="{Binding LocalName}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Grid>
</UserControl>
It looks so:
My control has ListView item, named as myListView. How can I set value for ItemsSource property of myListView through XAML for NameInfoControl instance? I need it in the next code:
<GroupBox Header="Command groups:" Grid.Column="0" Grid.Row="1" Margin="5">
<local:NameInfoControl/>
</GroupBox>
In your XAML of your NameInfoControl bind the items of your myListView to the DataContext of your control:
<ListView ItemsSource="{Binding}" x:Name="myListView" x:FieldModifier="public" Margin="3" Grid.Row="1">
And then in the parent XAML where you use that control bind the DataContext to the list that contain the items that should be displayed:
<local:NameInfoControl DataContext="{Binding MyCollectionOfItems}" />
I have a really simple WPF UserControl:
<UserControl x:Class="dr.SitecoreCompare.WPF.ConnectionEntry"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="connEntry"
BorderBrush="Navy" BorderThickness="1" Margin="5,0,0,5" >
<StackPanel Margin="0,10,0,0" >
<Label FontWeight="ExtraBold" Content="{Binding ElementName=connEntry, Path=Title}"></Label>
<Label Margin="0,5,0,0">Server:</Label>
<TextBox x:Name="txtServer" TabIndex="1" Text="{Binding Path=ServerName}" ></TextBox>
<Label>Database:</Label>
<TextBox x:Name="txtDatabase" TabIndex="2" Text="{Binding Path=DatabaseName}"></TextBox>
</StackPanel>
This is used twice in the same window. Now, I can select the first TextBox on both th instances of my UserControl, but the second ("txtDatabase") textbox cannot be selected, neither by tabbing or clicking. Why is this ? Am I missing something with regards to creating WPF usercontrols ?
EDIT:
DatabaseName is not readonly, it is a simple property. The XAML for the window the usercontrol is placed on looks like this:
<Window x:Class="dr.SitecoreCompare.WPF.ProjectDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:dr.SitecoreCompare.WPF"
Title="Choose project" Height="280" Width="500"
WindowStartupLocation="CenterOwner" WindowStyle="SingleBorderWindow" HorizontalAlignment="Center" ShowInTaskbar="False" ShowActivated="True" ResizeMode="NoResize" VerticalContentAlignment="Top" VerticalAlignment="Center">
<StackPanel>
<Label>Choose databases</Label>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<c:ConnectionEntry Grid.Column="0" x:Name="connMaster" Title="Master:" Padding="5" />
<c:ConnectionEntry Grid.Column="1" x:Name="connSlave" Title="Slave:" Padding="5" />
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0" >
<Button x:Name="btnCancel" Click="btnCancel_Click">Cancel</Button>
<Button x:Name="btnOK" Click="btnOK_Click">OK</Button>
</StackPanel>
</StackPanel>
</Window>
Try Mode=TwoWay in your binding. I've seen this where the initialization sets the value and the control can not set the the value.
<TextBox x:Name="txtDatabase" TabIndex="2" Text="{Binding Path=DatabaseName, Mode=TwoWay}"></TextBox>
This works in XamlPad, so I think there is something outside the code you posted that is causing the problem. Is DatabaseName readonly?