UserControl examples - c#

I am new to the WPF.
I wanted to create a UserControl which contains two fields for example
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="189*"/>
<ColumnDefinition Width="328*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="53*"/>
<RowDefinition Height="64*"/>
<RowDefinition Height="62*"/>
<RowDefinition Height="141*"/>
</Grid.RowDefinitions>
<TextBlock HorizontalAlignment="Right" TextWrapping="Wrap" Text="Name:" VerticalAlignment="Center"/>
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Center" Width="120" Grid.Column="1" Margin="3,0,0,0"/>
<TextBlock HorizontalAlignment="Right" TextWrapping="Wrap" Text="Age:" VerticalAlignment="Center" Grid.Row="1"/>
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Center" Width="120" Grid.Row="1" Grid.Column="1" Margin="3,0,0,0"/>
<Button Content="Add Person" HorizontalAlignment="Left" VerticalAlignment="Center" Width="75" Grid.Row="2" Grid.Column="1"/>
</Grid>
I wanted to create my user control in such a way that other developers(Who uses my usercontrol) can be able to add extra fields to it.
Imagine a developer want to add "Address filed to the above control".
If any one have sample articles on this please provide me.

I think you are after ContentControl. See below article for an example.
The ContentControl can contain any type of common language runtime
object (such as a string or a DateTime object) or a UIElement object
(such as a Rectangle or a Panel). This enables you to add rich content
to controls such as Button and CheckBox.
How to Embed Arbitrary Content in a WPF Control

Related

WPF showing Table using Grid in XAML

I am trying to show a Table using Grid in XAML in WPF.
My XAML code in my WPF app is like this-
<Grid ShowGridLines="True" Background="Yellow">
<Grid.ColumnDefinitions>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Text="Valid From" Grid.Row="0" Grid.Column="0" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding ValidFrom}" Grid.Row="0" Grid.Column="1" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="Valid To" Grid.Row="1" Grid.Column="0" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding ValidTo}" Grid.Row="1" Grid.Column="1" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="SigningTime" Grid.Row="2" Grid.Column="0" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<TextBlock Text="{Binding SigningTime}" Grid.Row="2" Grid.Column="1" FontSize="16" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
</Grid>
What I am getting like this-
I like to have a clean table, can anyone please help?
You only have two rows in the grid but three rows of data.
You should add another rowdefinition:
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
If you set grid.row to 2, the rows are zero based so this looks for a third row.
When there are less rows ( or columns ) than the attached property interpretation defaults to the last valid one and hence puts two sets of data into your second row with your current markup.

C# WPF - Creating Custom Control. Not sure how to align Text Correctly

I'm trying to create a custom control; similar, say to a Compass, so it is circular. I have a compass face image, and an arrow image that I can rotate to point the right direction. The problem is that I have N,S,E,W markers that I want to update at times and thus made them labels. I divided the field up into percentages and put the labels in the right grid locations.
This all looks great.
BUT when I use this custom control on various pages, some work and some don't. What it comes down to is the size of the cell of the grid on the new page. In one case the grid width is 4x the grid height. The background image grows to fill the height; this is right. The West and East TextBlocks are way off of the Compass_Face image because the 1/4th the width of the cell is way to the left. I thought that they would be constrained to the size of the custom control but that appears to not be the problem.
I'm sure that there has to be a way to keep the text constrained to the compass_face image. Thoughts?
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*"/>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="25*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<Image x:Name="imageBackground" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="3" Source="Resources/compass_face.png"/>
<Image x:Name="imageArrow" Grid.Column="1" Grid.Row="1" Source="Resources/arrow.png"/>
<TextBlock x:Name="labelNorth" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="N"/>
<TextBlock x:Name="labelSouth" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="S"/>
<TextBlock x:Name="labelEast" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="E"/>
<TextBlock x:Name="labelWest" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="W"/>
</Grid>
Grid isn't really the best layout to use in this case, but you can force it to be square by putting a Viewbox around it and assigning your parent grid to a specific size. That will keep your text aligned properly:
<Viewbox>
<Grid Width="200" Height="200">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*"/>
<ColumnDefinition Width="50*"/>
<ColumnDefinition Width="25*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25*"/>
<RowDefinition Height="50*"/>
<RowDefinition Height="25*"/>
</Grid.RowDefinitions>
<!--<Image x:Name="imageBackground" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="3" Source="Resources/compass_face.png"/>
<Image x:Name="imageArrow" Grid.Column="1" Grid.Row="1" Source="Resources/arrow.png"/>-->
<Ellipse Fill="CornflowerBlue" Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Grid.RowSpan="3" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="↑" FontSize="200" Foreground="White" HorizontalAlignment="Center" VerticalAlignment="Center" />
<TextBlock x:Name="labelNorth" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="N"/>
<TextBlock x:Name="labelSouth" Grid.Column="1" Grid.Row="2" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="S"/>
<TextBlock x:Name="labelEast" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="E"/>
<TextBlock x:Name="labelWest" Grid.Column="0" Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="White" FontWeight="Bold" Text="W"/>
</Grid>
</Viewbox>

IsDefault causes focus instead of click

I have a control with 3 text boxes and one Button that is set to IsDefault. When I am typing in one of the text boxes and press the Enter key I expect the IsDefault button to be clicked, instead it only focuses the button instead of clicking it. I have made sure that there are no other IsDefault buttons, I have checked that the IsDefaulted property of the Button is true when I press the enter button.
<Grid DockPanel.Dock="Top">
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<TextBlock Text="New:" VerticalAlignment="Center" Margin="5,0,0,0" Grid.Column="0"/>
<TextBox UndoLimit="10" Name="txtAddNew" Grid.Column="1" Height="23" Margin="10,0" VerticalAlignment="Center"/>
<TextBlock Text="Amendment:" VerticalAlignment="Center" Margin="5,0,0,0" Grid.Column="0" Grid.Row="1"/>
<TextBox UndoLimit="10" Name="txtAddAmend" Grid.Column="1" Height="23" Margin="10,0" VerticalAlignment="Center" Grid.Row="1"/>
<TextBlock Text="Unknown:" VerticalAlignment="Center" Margin="5,0,0,0" Grid.Column="0" Grid.Row="2"/>
<TextBox UndoLimit="10" Name="txtAddUnknown" Grid.Column="1" Height="23" Margin="10,0" VerticalAlignment="Center" Grid.Row="2"/>
<Idyllic:IdyllicButton DockPanel.Dock="Top" Margin="10,5" IsDefault="True" Name="btnAdd" Height="30" Grid.Row="3" Grid.ColumnSpan="2">
<StackPanel>
<Idyllic:CustomFillImage Image="{StaticResource Add}" Fill="{Binding RelativeSource={RelativeSource AncestorType=Button}, Path=Foreground}"/>
</StackPanel>
</Idyllic:IdyllicButton>
</Grid>
EDIT: The proposed question as duplication does not fix the issue, I do not want to set the focus of the button, that is my issue. When I press enter the button is focused instead of clicked. My button is already set to IsDefault.
I found the issue, the problem was that there was another User Control embedded in the control that also implements IsDefault, I suppose in that case the behavior is to focus the first IsDefault button on the page, including child User Controls.

Windows Store App - XAML - Border filling page rather then wrapping Grid

I'm trying to put a <Border/> around a <Grid/> in a page, however the border appears to be bordering the page rather than the grid.
This is only XAML in my page element.
<Border Background="Black">
<Grid Background="{ThemeResource ControlBackgroundBrush}" x:Name="LoginCredentials" Margin="5" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock TextWrapping="Wrap" Text="Username:" Style="{StaticResource SubheaderTextBlockStyle}" VerticalAlignment="Center" Grid.Row="0" HorizontalAlignment="Right" Margin="5"/>
<TextBox x:Name="UserName" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Center" Text="" Grid.Row="0" Grid.Column="1" TextChanged="UserChange" Margin="5"/>
<Button x:Name="LoginButton" Content="Login" Click="LoginButton_Click" Grid.Row="2" HorizontalAlignment="Right" Margin="5" TabIndex="0"/>
<Button x:Name="CancelButton" Content="Cancel" Click="CancelButton_Click" Grid.Row="2" Grid.Column="1" />
</Grid>
</Border>
As a test I created a resource to fill the background of the <Grid/> with a colour and also filled the background of the <Border/> with a different colour. The <Grid/> ends up as a box in the center of the screen as intended, but the border <Border/> fills the entire screen. Can anyone tell me why this happens and how to get the <Border/> to fit around the <Grid/> as I want?
Got it!
<Border Background="Black" VerticalAlignment="Center" HorizontalAlignment="Center">
....
</Border>
As soon as i posted the question, what i was missing became clear!

How can I keep dynamic sized controls aligned?

I have a WPF application and I am looking for a way to align some Label and TextBox controls so that the TextBox controls are always inline, but also allow for the Label content to be dynamic (which should move the TextBoxes as required).
It is a little hard to explain so here are a couple of screenshots that should show my requirements...
Before:
After:
Notice how the first TextBox shifts to the right in order to make room for the longer text, while the second TextBox also shifts to keep inline with the first. (The behavior I want is similar to that of an HTML table with two rows of two cells each)
Keeping in mind I am fairly new to WPF (so I may be going down the wrong road completely), I have used a couple of StackPanels in order to cater for the dynamic sized labels. However, the problem of course is that both StackPanels do not know about each other.
Here is my current code:
<StackPanel Orientation="Horizontal">
<Label Content="Label 1" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="200"/>
</StackPanel>
<StackPanel Orientation="Horizontal">
<Label Content="Label 2" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="200"/>
</StackPanel>
Is there anyway to get what I want by using StackPanels? If not, what other controls or methods can I use to meet my requirements?
If you want the columns to be sized the same for all controls, simply use a Grid.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="23"/>
<RowDefinition Height="23"/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Longer Label 1"/>
<TextBox Grid.Row="0" Grid.Column="1" TextWrapping="Wrap"/>
<Label Grid.Row="1" Grid.Column="0" Content="Label 2" />
<TextBox Grid.Row="1" Grid.Column="1" TextWrapping="Wrap"/>
</Grid>
With this setup, the first column will size to fit the widest label, and the second will take up the rest.
Just use a Grid:
<Grid Grid.Row="2" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
...
</Grid.RowDefinitions>
<TextBox Grid.Row="0" Grid.Column="0" Text="Name" Style="{StaticResource
LabelStyle}" />
<TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Name,
UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxStyle}" />
<TextBox Grid.Row="1" Grid.Column="0" Text="Age" Style="{StaticResource
LabelStyle}" />
<TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Age,
UpdateSourceTrigger=PropertyChanged}" Style="{StaticResource TextBoxStyle}" />
...
</Grid>

Categories

Resources