I want to share a parent column definition with a child grid.
I have a parent grid like:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<controls:GridEntry />
<controls:GridEntry />
<controls:GridEntry />
</Grid>
and a child that is a UserControl (controls:GridEntry) with following content:
<Grid>
<Label x:Name="caption" />
<TextBox x:Name="value" />
<Button x:Name="button" />
</Grid>
My current idea is to find the parent grid from the child and set the constraints (if possible as binding, otherwise copy. When copying I have to catch all resize operations manually).
Is there an easy way to transfer the ColumnDefinitions of the parent grid to the child grid (preferably via XAML)?
Related
My UWP app shows very limited part of the elements when inspected (neither with inspector.exe nor with Appium Client's Inspector). As a consequence, trying to locate them with Appium's FindElementByAccessibilityId results with NoSuchElementException.
Example:
<Page [namespaces]>
<Page.Resources>
[Resources]
</Page.Resources>
<Grid AutomationProperties.AutomationId="CreationModeRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="BackButton" />
<StackPanel x:Name="MainToolsPanel"
Orientation="Horizontal">
<controls:ToolBarButton x:Name="DrawingToolBallPen" />
<controls:ColorSelectorDropDown x:Name="ColorPaletteDropDown">
<PathIcon Width="44"
Height="44"
Data="{StaticResource ColorToolIcon}">
</PathIcon>
</controls:ColorSelectorDropDown>
</StackPanel>
</Grid>
<ScrollViewer x:Name="Scroll">
<inkCanvas:InkVectorCanvas x:Name="InkVectorCanvas" />
</ScrollViewer>
</Grid>
</Page>
From the above code, the only successfully inspected elements are the BackButton, DrawingToolBallPen & Scroll. Neither the CreationModeRoot, nor the MainToolsPanel, nor the nor the InkVectorCanvas are detected.
Please tell me how to properly construct my view.
I found the solution:
AutomationId and AutomationName are automatically mapped to x:Name and Content properties. If the content property is not string, most of the time inspecting tools fail to detect them. Overwriting AutomationName using AutomationProperties.Name PropertyPath resolves that problem.
What I need is to guaranty that all my columns aren't gonna be stretched by its content controls when they are bigger. Now it does. I found a solution here enter link description here. It works, but I'm wondering if it's possible to bind to item template Grid Width itself somehow instead of binding to the ListBox Width? And if it's possible is it proper way to go in terms of performance?
<telerik:RadListBox.ItemTemplate>
<DataTemplate>
<Grid> <-- need to bind this Grid Width
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" /> <-- to these columns width for further calculations
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
You can name the parent Grid and bind to it like:
<Grid x:Name="ParentGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=ActualWidth,
ElementName=ParentGrid,
Converter={StaticResource YourConverter}"/>
<!-- ... -->
</Grid.ColumnDefinitions>
<!-- ... -->
</Grid>
An other way is to bind the Grid as parent like:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=ActualWidth,
RelativeSource={RelativeSource AncestorType={x:Type Grid}},
Converter={StaticResource YourConverter}"/>
<!-- ... -->
</Grid.ColumnDefinitions>
<!-- ... -->
</Grid>
On my Window, I've got a GroupBox. I'd like to build out a horizontally aligned form inside of that GroupBox. By horizontally aligned, I mean a form where the label and the input reside on the same grid row or x axis. Separate form labels + inputs reside on their own row.
Since a GroupBox can only have one child content, I assume I need to either use a Grid or StackPanel. I'm trying to use a StackPanel because that seems simpler and should achieve what I'm aiming for.
The issue I'm trying to figure out is how to group the input and label into one unit so they can reside horizontally next to each other, but stack vertically as a pair within the StackPanel.
It's probably best to use a Grid that way you an get the labels and inputs to line up vertically. While it's not impossible with a stack panel it's a whole lot harder. If you set the grid's RowDefinition heights to "Auto" the grid will only be as tall as it needs to be:
<GroupBox>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Label1"/>
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Input1}"/>
<TextBlock Grid.Row="1" Grid.Column="0" Text="Label2"/>
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Input2}"/>
etc.
</Grid>
</GroupBox>
You'll probably need to play around with margins and/or padding and horizontal alignments to get the layout exactly how you want it, but this should give you the control you need to achieve what you want.
you can use a stackpanel with orientation equal to vertical inside your groupbox and inside that stackpanel you can have another stackpanel with orientation equal to horizantal for your label and input just like following sample code.
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical">
<StackPanel Name="input1" Orientation="Horizontal">
<Label Content="input1"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input2" Orientation="Horizontal">
<Label Content="input2"/>
<TextBox/>
</StackPanel>
<StackPanel Name="input3" Orientation="Horizontal">
<Label Content="input3"/>
<TextBox/>
</StackPanel>
</StackPanel>
</GroupBox>
One feature you might find useful is grid shared size scope. It can help you align elements in multiple different Grids, by sharing their column\row sizes, like this:
<GroupBox Header="Sample GroupBox">
<StackPanel Orientation="Vertical" Grid.IsSharedSizeScope="True">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input11" Grid.Column="0" />
<TextBox Grid.Column="1" Width="100"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input2222222" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="firstGroup" />
<ColumnDefinition Width="Auto" SharedSizeGroup="secondGroup" />
</Grid.ColumnDefinitions>
<Label Content="input3333333333333" Grid.Column="0" />
<TextBox Grid.Column="1"/>
</Grid>
</StackPanel>
</GroupBox>
I don't say that it is necessary in the code above, but that is just example. Often, you want to use grid in for example ItemTemplate of ItemsControl, and you want all items to be aligned. Here shared size scope might help.
I have started with XAML as part of my freetime and now I have a problem with the padding of the standard button.
I have the following code for a grid which resides in another grid, so I have four grids inside my page and the problem is that the buttons are cut off and I am not able to change the width or the padding of the buttons.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Name}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Center" FontSize="24"/>
<Button x:Name="Player2MinusButton" Content="-" Grid.Row="1" Grid.Column="0" FontSize="20" ></Button>
<Button x:Name="Player2PlusButton" Content="+" Grid.Row="1" Grid.Column="2" FontSize="20" ></Button>
</Grid>
The problem is now, that the button is cut of as you could see in the screenshot here:
I have already tried to set a negative padding/margin and also to make a Custom Style:
<Style TargetType="Button" x:Key="ButtonStyle">
<Setter Property="Padding" Value="-10,0"/>
</Style>
Thanks for your hints and I hope I have nothing forgotten in my first question.
Michael
Since you want a narrower than standard button set the Buttons' MinWidth property:
<Button x:Name="Player2PlusButton" Content="+" Grid.Row="1" Grid.Column="2" FontSize="20" MinWidth=50 AutomationProperties.Name="Plus Button" ></Button>
If you copy the button template (right click on the button in the designer then select Edit Template... and follow the prompts) you'll find the following:
<x:Double x:Key="PhoneButtonMinHeight">57.5</x:Double>
<x:Double x:Key="PhoneButtonMinWidth">109</x:Double>
I assume you're running on the phone: the Windows Store Button template is different and doesn't set the minimums. Your buttons come out small there by default.
I have run into a bizarre problem. I am displaying a UserControl within a UserControl and at the moment each contains a completely identical ListView, as in I copied and pasted it from one to the other. On the parent UserControl, the ListView displays properly, but on the sub-UserControl (whatever it's called), the ListView columns refuse to stretch to fit their content. I have no idea why this is happening since the code of both ListViews is exactly the same. Both are placed directly on the grid.
On the top left is the ListView from the parent control and on the bottom right is that of the child control. Here is the code for both ListViews:
<ListView ItemsSource="{Binding Adventurers}"
Name="AdvListView"
HorizontalAlignment="Stretch"
Grid.Column="2"
Grid.ColumnSpan="1"
Grid.Row="2"
ScrollViewer.CanContentScroll="False"
BorderThickness="3">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<cmd:EventToCommand Command="{Binding ShowAdvWindowCommand}"
CommandParameter="{Binding ElementName=AdvListView, Path=SelectedItem}"
PassEventArgsToCommand="False" />
</i:EventTrigger>
</i:Interaction.Triggers>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="VerticalContentAlignment" Value="Stretch" />
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="NameTemplate">
<TextBlock Grid.Column="1" Grid.Row="0" Text="{Binding Name}" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" />
</DataTemplate>
<DataTemplate x:Key="StatusTemplate">
<TextBlock Margin="2,1,1,1" Text="{Binding Status}" VerticalAlignment="Center" />
</DataTemplate>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Name" CellTemplate="{StaticResource NameTemplate}" />
<GridViewColumn Header="Status" CellTemplate="{StaticResource StatusTemplate}" />
</GridView>
</ListView.View>
</ListView>
Why would this work on one and not the other? I'm really at a loss at this point.
Update: In the parent UserControl, the grid layout is:
<Grid Background="White">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
//Listview here among other controls
</Grid>
In the child:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
//Listview here
</Grid>
Modifying Grid.Row, Grid.Column, RowSpan, or ColumnSpan to be correct doesn't fix the problem.
Update: A bit more info that may be relevant: When I try to use Snoop on my program. I get this error:
"BindingFailure was detected - The assembly with display name 'Snoop.XmlSerializers' failed to load in the 'LoadFrom' binding context of the AppDomain with ID 1. The cause of the failure was: System.IO.FileNotFoundException: Could not load file or assembly 'Snoop.XmlSerializers, Version=2.8.0.0, Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified."
Snoop has no problem with other programs. I don't know if this is related to the issue at all, but I figured I'd post it anyways.
Update: I don't think this would matter, but just to be thorough, here is where the child UserControl is created within the parent:
<Grid>
//Other controls
<UserControl Grid.Column="3"
Grid.Row="3"
Visibility="{Binding AdventurerInfoVisibility}">
<view:AdventurerInfoView />
</UserControl>
</Grid>
At this point I'm completely stumped. I can create a copy of the ListView in the parent UserControl and have it display properly... but for some reason it doesn't want to behave in the child UserControl... I'm open to any ideas and if you need more code I would be more than happy to provide it.
After much tinkering and frustration, I found out what was causing the problem. The child UserControl's Visibility was set to Collapsed by default and was made visible by a button click. When I made it visible by default, the columns stretched properly.
Now I just need to find out how to allow it to start collapsed and still maintain the stretched column width.
I create a deom use your code, and it does not to repeat your problem.
I think maybe your child usercontrol had some TextBlock style, and override your container setting.