ReactiveUI - Views not rendering properly (or in full) - c#

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.

Related

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>

Adding a UserControl to a TabItem

Originally I had my MainWindow(.xaml) that had a stackpanel and a frame. Within the stackpanel were three navigation buttons and the frame had one of the three Pages (based on which navigation button the user clicked). However, it seems that since I'm not doing a web app, that using Frame (and Pages?) is not the right way to go about it. So I changed the stackpanel and frame to a single tabcontrol (with tabs being what were the three buttons before). I also changed the Pages to usercontrols.
However, I'm having trouble finding a way to put the Pages (now UserControls) into the content of the tabitem, without using a Frame. I'm trying to do all of this within the MainWindow xaml.
my MainWindow.xaml:
<Window x:Class="ConstructedLanguageOrganizerTool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" mc:Ignorable="d" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" Height="454" Width="573">
<Grid>
<TabControl HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Name="tabControl1">
<TabItem Header="Basics" Name="basicsTab">
//What can I use here instead of Frame?
</TabItem>
<TabItem Header="Words" Name="wordsTab">
<Grid>
<Frame Source="WordsPage.xaml"/>
</Grid>
</TabItem>
...
</TabControl>
</Grid>
</Window>
Am I going about this the wrong way? I think that I'm suppose to use some sort of databinding, maybe? Although, the more I look at things on data binging, the more I just get confused on that as well.
edit: here is my BasicsPage.xaml
<UserControl x:Class="ConstructedLanguageOrganizerTool.BasicsPage"
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" x:Name="basicsPage" Height="349" Width="334">
<Grid>
// Grid Row and Column defs here
//Number of textboxs and textblocks here.
</Grid>
</UserControl>
You just need to create an instance of UserControl and put it inside TabItem.
Say BasicsPage is your UserControl you want to put inside TabItem. All you have to do this:
<TabItem Header="Basics" Name="basicsTab">
<local:BasicsPage/>
</TabItem>
Define local namespace at root window where BasicsPage is defined in something like:
<Window x:Class="ConstructedLanguageOrganizerTool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ConstructedLanguageOrganizerTool"> <-- HERE

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>

Adding a WPF UserControl programmatically has no style

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.

Twoway binding causes strange behaviour in maps control for wp7

I'm developing an application for windows phone using the maps control. The map control binds its center and its zoomlevel property to two properties on a viewmodel.
The map control is on a page seperate from the mainpage of the application. Every time a user moves to the map the page binds to a viewmodel. This viewmodel is a singleton (always the same instance).
the first time I move to the map navigating on the map works fine, but when I go back and navigate to the map again, navigation has some sort of bounce like it is push backed to its initial location.
To see this behaviour do the following:
Navigate to the mapPage bij clicking on the button on the mainpage. At this time the map control works as expected.
Click the back button to return to the mainpage.
Click the button on the mainpage again to navigate to the mappage for the second time. Now when sliding the map the control behaves strange by bouncing back to the original location before sliding.
The mainpage contains just a button to navigate to the map page which looks as follows:
<phone:PhoneApplicationPage
x:Class="MapTester.Map"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:maps="clr-namespace:Microsoft.Phone.Controls.Maps;assembly=Microsoft.Phone.Controls.Maps"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d" d:DesignHeight="768" d:DesignWidth="480"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Path=MapViewModel, Source={StaticResource ViewModelLocator}}">
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<maps:Map Center="{Binding Center, Mode=TwoWay}"
ZoomLevel="{Binding ZoomLevel,Mode=TwoWay}"
ZoomBarVisibility="Visible"
CredentialsProvider=""
ScaleVisibility="Visible"></maps:Map>
</Grid>
</phone:PhoneApplicationPage>
The MapViewModel is defined on the ViewModelLocator. I created a solution to demonstrate then problem. You can download it here https://skydrive.live.com/?cid=25374d9051083633&sc=documents&id=25374D9051083633%21344#
Does anybody have an idea how to fix this?
Thanks!
I don't see what's wrong here? Unless you're navigating backwards (and thus not setting the DataContext), Bing Maps will always do a "bounce" animation from global view to the center location. This is how the control work, so nothing you can do about that.

Categories