Adding a WPF UserControl programmatically has no style - c#

I'm trying to create a button-like UserControl which consists of a border and a label. When adding this UserControl directly in the XAML of MainWindow, it renders correctly (it is put in a WrapPanel), but if I add it programmatically it doesn't look the same at all. There is no border, no background color, the text size of the label is wrong and so is the text color.
This is my user control:
<UserControl x:Class="Jishi.SonosPartyMode.UserControls.Player"
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="150" d:DesignWidth="300"
Width="200"
Height="100">
<Border BorderBrush="#086EAA" CornerRadius="8,8,8,8" BorderThickness="4" Margin="15" Padding="15px" VerticalAlignment="Center" Background="#0A4069">
<Label Name="PlayerName" TextElement.Foreground="White" TextElement.FontSize="20px">asdasdasd</Label>
</Border>
</UserControl>
when adding it, I just invoke it like this:
var button = new Player { Content = player.Properties.RoomName, DataContext = player.Properties.UDN };
PlayerList.Children.Add( button );
PlayerList is the actual WrapPanel and Player is my UserControl. I have tried finding information regarding this, but I don't find anything. If you have another approach that I can take, please come with suggestions. All I want is a clickable area with some rounded corners that can contain text (one or more rows).
I can apply styles programatically, but the styles defined in the xaml for the UserControl isn't preserved (Border, Margins, colors etc).

First of all, you don't need to create a custom control for this, you can easily do
var button = new Border { *border properties*, Content = new Lable {Content="dfsdfsdfsd"}};
And if you use PlayerList.Children.Add( button ); then it adds to the end of Wrappanel and in XAML code you add it not as the last element (maybe)..
And the last idea is that you lost some properties that you added in XAML when test it (like aligment, margin, etc.)
Hope this helps.

Related

ReactiveUI - Views not rendering properly (or in full)

I'm in the process of starting a new project, using ReactiveUI and MahApps.Metro. The first hurdle I've hit is a problem of views not showing in their entirety. I have a Window, and in that Window I have a ViewModelViewHost from the RxUI library. It is a simple container for a nested view-model. The ActiveItem binding is properly binded to the view-model of the User Control, and the Button from the user control is visible on screen.
What I expect to see is a Window with a dark gray background and a button in the middle. What I see is the Window with its default background and a Button in the middle. This is not right. If I remove the button, I see nothing on the Window, only the default background.
It seems the ViewModelViewHost is only showing the actual contents of a UserControl and is disregarding what isn't considered a real Control, such as grids etc.
Has anyone come across this behaviour before?
<mah:MetroWindow x:Class="...MainWindow"
xmlns:mah="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:rx="clr-namespace:ReactiveUI;assembly=ReactiveUI"
WindowStartupLocation="CenterScreen"
ShowTitleBar="False"
ShowCloseButton="False"
ShowMaxRestoreButton="False"
ShowMinButton="False"
Height="768"
Width="1024">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center">
<rx:ViewModelViewHost ViewModel="{Binding ActiveItem}" />
</Grid>
</mah:MetroWindow>
<UserControl x:Class="...NestedView"
Name="TheUserControl"
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"
TextOptions.TextHintingMode="Auto"
TextOptions.TextRenderingMode="Auto"
d:DesignHeight="768" d:DesignWidth="1024">
<Grid Background="DarkGray">
<Button Width="200" Height="100" />
</Grid>
</UserControl>
This won't be a ReactiveUI problem, just a simple WPF one.
The ViewModelViewHost is centered in your window. While your UserControl has a DesignHeight and DesignWidth set, when it's rendered at runtime it will automatically size itself to the height and width of its content - the Button.
Add VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" to your ViewModelViewHost declaration and remove the other two Alignment attributes (they default to Stretch) and it should stretch its contents to the size of the Window while centering any item that has a fixed size.

resize child content of element host with form resize

I am completely new to WPF and have to do a bit of work on it for my job. I have a form which contains 3 element hosts each with their own child controls. I need the child controls to resize with the form so they grow and shrink when the form does.
Only the element hosts themselves seem to have the anchor property which is what I understand I need to manipulate to achieve this. How can I get the child controls to resize as well as the element hosts or am I doing this completely wrong?
Any help would be great.
I've tested with a standard text box control, and setting the Anchor property of that to Top, Left, Bottom works fine. I don't understand why it doesn't work for the element host content
<UserControl x:Class="MyControls.ucEventViewerOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/,arkup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="297" d:DesignWidth="128" Loaded="UserControl_Loaded">
<Grid Width="96" Height="288">
<DataGrid AutoGenerateColumns="False" Height="288" HorizontalAlignment="Left" Name="dgEventViewerOptions" VerticalAlignment="Top" Width="96" SelectionChanged="dgEventViewOptions_SelectionChanged" />
</Grid>
</UserControl>
In WPF, this type of behavior is generally caused by the HorizontalAlignment and VerticalAlignment properties. Ommitting these properties will set them to their default value "Stretch" and allows controls to resize in relation to their parent containers. This is only possible when the controls are not assigned with fixed sizes, though.
In your case, you may simply ommit these properties:
<UserControl x:Class="MyControls.ucEventViewerOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/,arkup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="297" d:DesignWidth="128" Loaded="UserControl_Loaded">
<Grid>
<DataGrid AutoGenerateColumns="False" Name="dgEventViewerOptions" SelectionChanged="dgEventViewOptions_SelectionChanged" />
</Grid>
</UserControl>
Unless you wish them to have a fixed height or width, of course.
If you want items to resize depending on parent elements size, you have to keep in mind that controls are implicitly inheriting parents' stretching behavior when size is not set explicitly. So to fix your problem, you need to remove setting Width and Height explicitly:
<Grid>
<DataGrid AutoGenerateColumns="False" Name="dgEventViewerOptions" SelectionChanged="dgEventViewOptions_SelectionChanged" />
</Grid>

How to Set listbox location in WPF [duplicate]

This question already has answers here:
C# WPF how to set location,width and height of the controls programmatically?
(6 answers)
Closed 8 years ago.
i want to set listbox location. In Winform i did this by using this code listbox.Location but in WPF there is no listbox.Location property.
Edit 1:
var rect = txtBox.GetRectFromCharacterIndex(txtBox.CaretIndex);
var point = rect.BottomRight;
lstBox1.Visibility = Visibility.Visible;
//Want to achieved this
//TextBox.Location = point;
I am creating something like Intellisense with listbox
You should probably read up on WPF layouts, however to you can use the ListBox.Margin to position the ListBox in a hardcoded location.
listbox.Margin = new Thickness( 25, 200, 0, 0 );
or in XAML
<ListBox Margin="25,200,0,0"/>
A ListBox's location is determined relative to the control it is contained in. To set a location within it's parent control you can use the HorizontalAlignment, VerticalAlignment and Margin Properties.
Here is an example:
<Window x:Class="WpfApplication14.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ListBox HorizontalAlignment="Left" Height="100" Margin="197,105,0,0" VerticalAlignment="Top" Width="100"/>
</Grid>
</Window>
Note - all these properties are available programmatically as well.
Thanks,
Eric
It all depends on what the parent panel is to determine how to set the position of your listbox. You'll need to read more about Layouts in WPF. Let's look at 2 panels to get you started, Grid and Canvas.
<Grid>
<ListBox x:Name="lb" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
lb.Margin = new Thickness(10,10,0,0);
The example above sets the ListBox lb in the Grid at position (10,10).
<Canvas>
<ListBox x:Name="lb"/>
</Canvas>
Canvas.SetTop(lb, 10);
Canvas.SetLeft(lb, 10);
The example above does the same for lb in a Canvas.
As you can see, it depends on what type of panel that you put your listbox into to be able to set the position correctly.

WPF - Setting window size to child usercontrol size

I have a tab control that is dynamically populated with tabs that contain user controls of various sizes. When a tab is opened I want the window to automatically resize to a size that makes sense given the active user control. Is there a clean way to do this?
I'm using a standard mvvm pattern.
Use the SizeToContent property on the Window class.
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
SizeToContent='Width'>
<Grid>
<Button Width='200' Content='The Button' />
</Grid>
</Window>

Where to put WPF Dynamic Control Creation Code

I am just in the process of teaching myself WPF. I have reached the point of adding controls dynamically and have hit a brick wall on something really simple. I code that should create a button (shown below):
Button button = new Button() { Height = 80, Width = 150, Content = "Test" };
parentControl.Add(button);
My question is what is parentControl actually called? I am using the standard Visual Studio 2012 WPF template and my main window is called MainWindow. I have no objects in the Window besides what comes in the template
So far I have looked at:
WPF runtime control creation
Dynamic control creation in WPF
WPF MVVM Dynamic control creation
Dynamic creation of control
Where should I put WPF specific code when using MVVM?
Steps Of Control Creation Process WPF
Where to put code in (primarily) windowless WPF app?
The closest I have found it: WPF runtime control creation.
All of these questions just assume you know such a basic thing but I don't. Please help.
I think I understand your question. If your XAML code looks like:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
</Window>
Then your codebehind should be something like:
public MainWindow()
{
InitializeComponent();
Button button = new Button() { Height = 80, Width = 150, Content = "Test" };
//In case you want to add other controls;
//You should still really use XAML for this.
var grid = new Grid();
grid.Children.Add(button);
Content = grid;
}
However, I warmly suggest you to use XAML as much as you can. Furthermore, I wouldn't add controls from the constructor but I'd use the Loaded event of the window. You can add a handler to the event in codebehind from the constructor, or directly in XAML. If you wanted to have the same result as above in XAML, your code would be:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Height="80" Width="180" Content="Test"/>
</Grid>
</Window>

Categories