Textbox focus does not work - wpf

I am using VS2015 and currently I am under pressure of this issue and I don't know why it's not working on VS2015.
I do have a "Splash Screen" which is a welcome page and after that will be another page to show some other forms. I do have 5 borders represent as a container, each border will show after hit next and all of the borders are place only in the same View which is MainWindow.xaml.
Every field just like Name textbox field do have a Validation.ErrorTemplateand I am not sure if that will affect the textbox focus.
I used FocusManager.FocusedElement and text1.focus() but still not working and other solution coming from other people having similar issues but still not working in my end.
I am guessing something in logical focus but when I force to focus the textbox still not working.
Simple example of XAML.
<Border x:Name="Panel1" Opacity="0" IsHitTestVisible="False"
RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform />
<TranslateTransform Y="515" />
</TransformGroup>
</Border.RenderTransform>
<Grid Background="{DynamicResource ActiveBrush}">
<ScrollViewer Margin="0,10,0,76.33" Height="450" Width="630" VerticalAlignment="Top"
VerticalScrollBarVisibility="Auto"
Template="{DynamicResource ContentPanelScrollviewerStyle}">
<StackPanel Orientation="Vertical" Width="630">
<Label Content="Name" HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="{DynamicResource FieldGroupHeadingTextSize}"
Foreground="{DynamicResource TextBrush}" />
<Grid Height="170">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid Column="0" IsVisibleChanged="Grid_IsVisibleChanged">
<StackPanel>
<Label Content="Name"
HorizontalAlignment="Left"
VerticalAlignment="Top"
FontSize="{DynamicResource FieldLabelTextSize}"
Foreground="{DynamicResource TextBrush}" />
<TextBox Name="text1" Validation.ErrorTemplate="{StaticResource validationTemplate}"
HorizontalAlignment="Left" TextWrapping="Wrap"
Text="{Binding Name, NotifyOnValidationError=True}"
VerticalAlignment="Top" Width="298.8" Height="24"
FontSize="{DynamicResource FieldInputTextSize}"
Foreground="{DynamicResource TextBrush}">
<i:Interaction.Behaviors>
<behaviors:ReadOnlyWhileValidatingBehavior />
</i:Interaction.Behaviors>
</TextBox>
</StackPanel>
</Grid>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Border>

Related

Responsive wpf Window

I am new with WPF please keep that in mind. I am trying to Make the Window Responsive to Resize, Is it possible that my controls such as textboxes and buttons are Resized as window grows or shrinks?
<Window x:Class="WPF_Working_Experimenet.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="216.586" Width="459.256">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="156*"/>
<ColumnDefinition Width="295*"/>
</Grid.ColumnDefinitions>
<Label Content="username :" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="66,27,0,0" Height="30" Width="63" FontFamily="B Nazanin" FontSize="15" Grid.Column="1"/>
<Label Content="password :" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="74,63,0,0" Height="30" Width="55" FontFamily="B Nazanin" FontSize="15" Grid.Column="1"/>
<Label x:Name="lblwrong" Content="" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="10,150,0,0" ClipToBounds="True" Grid.Column="1" Height="26" Width="275"/>
<Button x:Name="btnLogin" Content="Login" HorizontalAlignment="Left" VerticalAlignment="Top" Width="60" Grid.Column="1" Margin="211,103,0,0" Height="37" Background="White" Click="btnLogin_Click" BorderBrush="Red" FontFamily="B Nazanin" FontSize="15"/>
<Image HorizontalAlignment="Left" Height="117" Margin="4,23,0,0" VerticalAlignment="Top" Width="178" Source="img/Ticket_5523675581838074942.png" Grid.ColumnSpan="2" RenderTransformOrigin="0.5,0.128"/>
<Button x:Name="btnExit" Content="Exit" HorizontalAlignment="Left" VerticalAlignment="Top" Width="60" Grid.Column="1" Margin="146,103,0,0" Height="37" Background="#FFFDFDFD" BorderBrush="Red" Click="Button_btnExit" FontFamily="B Nazanin" FontSize="15"/>
<TextBox x:Name="txtUsername" HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" VerticalAlignment="Top" Width="125" Grid.Column="1" Margin="146,34,0,0" BorderBrush="#FFF7311E"/>
<PasswordBox x:Name="txtPassword" Grid.Column="1" HorizontalAlignment="Left" Margin="146,70,0,0" VerticalAlignment="Top" Width="125" Height="23" BorderBrush="#FFFD3306"/>
</Grid>
</Window>
Any Reference/hint or Tutorial/link would be lovely. thank you in advance
You have to set Margin / Padding instead of explicit Width / Height if you want your controls to grow / shrink.
Few links to help you :
Layout with Absolute and Dynamic Positioning
How to make all controls resize accordingly proportionally when window is maximized?
Controls do not resize if you set their Width and Height properties explicitly. Try the following, I removed the Width and Height properties and changed the HorizontalAlignment and VerticalAlignment values to Stretch.
<Window x:Class="WPF_Working_Experimenet.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="216.586" Width="459.256">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="156*"/>
<ColumnDefinition Width="295*"/>
</Grid.ColumnDefinitions>
<Label Content="username :"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
FontFamily="B Nazanin"
FontSize="15"
Grid.Column="1"/>
<Label Content="password :"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
FontFamily="B Nazanin"
FontSize="15"
rid.Column="1"/>
<Label x:Name="lblwrong"
Content=""
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
ClipToBounds="True"
Grid.Column="1"/>
<Button x:Name="btnLogin"
Content="Login"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1"
Background="White"
Click="btnLogin_Click"
BorderBrush="Red"
FontFamily="B Nazanin"
FontSize="15"/>
<Image HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Source="img/Ticket_5523675581838074942.png"
Grid.ColumnSpan="2"
RenderTransformOrigin="0.5,0.128"/>
<Button x:Name="btnExit"
Content="Exit"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.Column="1"
Background="#FFFDFDFD"
BorderBrush="Red"
Click="Button_btnExit"
FontFamily="B Nazanin"
FontSize="15"/>
<TextBox x:Name="txtUsername"
HorizontalAlignment="Stretch"
TextWrapping="Wrap"
VerticalAlignment="Stretch"
Grid.Column="1"
BorderBrush="#FFF7311E"/>
<PasswordBox x:Name="txtPassword"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="#FFFD3306"/>
</Grid>
</Window>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="View/Images/LoginImg.jpg" Stretch="Fill" Grid.Column="0" Grid.ColumnSpan="3">
<Image.Effect>
<BlurEffect Radius="8"/>
</Image.Effect>
</Image>
<TextBox Grid.Column="0" Grid.ColumnSpan="3" BorderBrush="Transparent" BorderThickness="0" Background="Transparent" Foreground="White" HorizontalAlignment="Center"
Height="78" Margin="122,10,45.6,0" TextWrapping="Wrap" Text="Library Management System " VerticalAlignment="Top" Width="594" FontSize="40" FontWeight="Bold" FontStyle="Normal">
<TextBox.VerticalContentAlignment>Center</TextBox.VerticalContentAlignment>
<TextBox.IsReadOnly>True</TextBox.IsReadOnly>
</TextBox>
<Canvas Grid.Column="1" HorizontalAlignment="Stretch" Width="auto" Height="300" VerticalAlignment="Stretch" RenderTransformOrigin="0.5,0.5" Background="White">
<Canvas.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="0.627"/>
<TranslateTransform/>
</TransformGroup>
</Canvas.RenderTransform>
<Label Content="Login" VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch" Background="BurlyWood" FontSize="15" Height="52" Width="254">
<Label.FontWeight>Bold</Label.FontWeight>
</Label>
<TextBox Height="24" Canvas.Left="20" TextWrapping="Wrap" Text="User Name" TextAlignment="Center" Canvas.Top="84" Width="120" Foreground="Gray"/>
<PasswordBox Canvas.Left="20" Canvas.Top="136" Height="34" Width="120"/>
</Canvas>
</Grid>
Setting the horizontal and vertical alignment to stretch instead of setting width and height of the widget will do the trick. But still you can set a margin if you want. Tried this out and it ensured that when the window size is changed the widget will adjust respectively.

How to overlay two gauge controls?

I've set up binding of a double value to an AngularBlockBar control. There are two gauges in the layout, but the AngularBlockBar which is over layed on top of the AngularGauge doesn't show its binding value updating on screen, although valid binding values are being updated to it.
To debug this, I've checked first that the binding value that is bound to the AngularBlockBar is valid and this shows as true by setting a break point.
The binding value shows as valid.
I'm thinking its because of the way the two gauges are over layed over each other, which causes the AngularBlockBar's binding to not show.
Does anyone know what the issue could be here, that prevents the AngularblockBar's binding from being shown on screen?
The layout below is the main user control of the application where the two gauges are over layed. The first gauge updates correctly with a white fill value as shown in the screen shot below. But the AngularBlockBar which has a blue fill value isn't updated
<UserControl
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:gauges="http://gu.se/Gauges"
xmlns:local="clr-namespace:MyoTestv4"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" x:Class="MyoTestv4.AdductionAbductionFlexionView"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Viewbox>
<Grid HorizontalAlignment="Left" Height="280" Margin="10,10,0,0" VerticalAlignment="Top" Width="280">
<TextBox HorizontalAlignment="Left" x:Name="statusTbx" Background="#141c28" Foreground="White" BorderBrush="#141c28" Height="30" Margin="0,3,0,0" TextWrapping="Wrap" Text="{Binding CurrentStatus}" VerticalAlignment="Top" Width="75"/>
<TextBox HorizontalAlignment="Left" x:Name="poseStatusTbx" Background="#141c28" Foreground="White" BorderBrush="#141c28" Height="39" Margin="80,4,0,0" TextWrapping="Wrap" Text="{Binding PoseStatus}" VerticalAlignment="Top" Width="75"/>
<TextBox HorizontalAlignment="Left" x:Name="degreeOfAbductionTbx" Background="#141c28" Foreground="White" Height="22" Margin="0,246,0,0" TextWrapping="Wrap" Text="{Binding DegreeStatus}" VerticalAlignment="Top" Width="47"/>
<Label Content="Arc start:" Foreground="#00bdde" HorizontalAlignment="Left" Margin="0,186,0,0" VerticalAlignment="Top" Width="57"/>
<Image HorizontalAlignment="Left" Source="pack://application:,,,/Images/abduction_side_trans.png" x:Name="exerciseImage" Height="100" Margin="0,33,0,0" VerticalAlignment="Top" Width="100"/>
<TextBox HorizontalAlignment="Left" x:Name="painfulArcEndTbx" Background="#141c28" Foreground="White" Height="22" Margin="62,217,0,0" TextWrapping="Wrap" Text="{Binding EndDegreeStatus}" VerticalAlignment="Top" Width="48"/>
<Label Content="Arc end:" Foreground="#00bdde" HorizontalAlignment="Left" Margin="0,217,0,0" VerticalAlignment="Top" Width="57"/>
<TextBox HorizontalAlignment="Left" x:Name="painfulArcStartTbx" Background="#141c28" Foreground="White" Height="23" Margin="62,189,0,0" TextWrapping="Wrap" Text="{Binding StartDegreeStatus}" VerticalAlignment="Top" Width="48"/>
<Grid>
<gauges:AngularGauge
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
IsDirectionReversed="False"
MajorTickFrequency="8"
FontSize="10"
MajorTicks="10"
MaxAngle="0"
Maximum="180"
MinAngle="-180"
Minimum="0"
Style="{StaticResource FatAngular}"
MinorTickFrequency="4"
Value="{Binding DegreeStatus}" Margin="149,2,-89,2" RenderTransformOrigin="0.5,0.5" Height="Auto" Width="Auto"
>
<gauges:AngularGauge.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="-89.642"/>
<TranslateTransform/>
</TransformGroup>
</gauges:AngularGauge.RenderTransform>
</gauges:AngularGauge>
<gauges:AngularBlockBar
MaxAngle="180"
Maximum="1"
MinAngle="0"
Minimum="0"
Opacity="0.2"
ReservedSpace="50"
Margin="149,2,-96,0"
TickLength="55"
Fill="DodgerBlue"
Value="{Binding PainfulArcStatus}"
RenderTransformOrigin="0.5,0.5" >
<gauges:AngularBlockBar.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="90.711"/>
<TranslateTransform/>
</TransformGroup>
</gauges:AngularBlockBar.RenderTransform>
</gauges:AngularBlockBar>
</Grid>
<TextBlock HorizontalAlignment="Left" x:Name="repCntTblk" Margin="80,43,0,0" TextWrapping="Wrap" Text="" FontSize="38" Foreground="#00bdde" VerticalAlignment="Top" Width="34" Height="41"/>
<Button Content="Submit" x:Name="submitBtn" Command="{Binding Path=DataSubmitCommand}" IsDefault="True" IsCancel="True" HorizontalAlignment="Left" Background="#00bdde" Foreground="White" Margin="0,148,0,0" VerticalAlignment="Top" Width="75" RenderTransformOrigin="0.76,5.093"/>
</Grid>
</Viewbox>
</UserControl>
The first gauge binding being shown, but the over layed value for the block bar isn't shown.
Don't you need to define Grid.Column and/or Grid.Row on your guage and blockbar other wise they will just lay ontop of eachother?
example with Grid.ColumnDefinitions, you probably want RowDefinitions
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100px"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ComboBox ItemsSource="{Binding NavigationItems}" SelectedItem="{Binding SelectedNavigationItem, Mode=TwoWay}" Grid.Row="0" Grid.Column="0">
</ComboBox>
<ContentControl Content="{Binding SelectedNavigationItem}" Grid.Row="0" Grid.Column="1"/>
</Grid>

TextBlock and Image inside Dockpanel

I have the below code. I am trying to place the image directly to the right of the textblock within the border, but the image is almost touching the right side of the screen. How can I allign the image to the right of the textblock
<Border BorderBrush="#FFD6D4D4" BorderThickness="0,0,0,1" Grid.Column="0" Grid.Row="1"
Height="28" VerticalAlignment="Top" Background="#FFF7F7F7"
HorizontalAlignment="Stretch">
<DockPanel LastChildFill="False">
<TextBlock DockPanel.Dock="Left"
Style="{StaticResource HeaderTextBlockStyle}"
Text="Check new items"
VerticalAlignment="Center" Margin="2" />
<Image
DockPanel.Dock="Left"
VerticalAlignment="Center"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Media/pointer.png"
RenderTransformOrigin="0.95,4.046"
HorizontalAlignment="Center" Margin="0"
Height="25.306" Width="25.008>
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="49.57"/>
<TranslateTransform X="-39.746" Y="-21.185"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</DockPanel>
</Border>
Try using the Grid control and define two columns into it
<Border BorderBrush="#FFD6D4D4" BorderThickness="0,0,0,1" Grid.Column="0" Grid.Row="1"
Height="28" VerticalAlignment="Top" Background="#FFF7F7F7"
HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<Column Definition Width="*"/>
<Column Definition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Style="{StaticResource HeaderTextBlockStyle}"
Text="Check new items"
VerticalAlignment="Center" Margin="2" />
<Image
Grid.Column="1" VerticalAlignment="Center"
SnapsToDevicePixels="True"
UseLayoutRounding="True"
RenderOptions.BitmapScalingMode="HighQuality"
Source="/Media/pointer.png"
RenderTransformOrigin="0.95,4.046"
HorizontalAlignment="Center" Margin="0"
Height="25.306" Width="25.008>
<Image.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform Angle="49.57"/>
<TranslateTransform X="-39.746" Y="-21.185"/>
</TransformGroup>
</Image.RenderTransform>
</Image>
</Grid>
</Border>
Try using a StackPanel with Orientation set to horizontal instead of the dockpanel. That should put the image right next to the textblock.
if you still want to use the dock panel try setting the margin you want, on the image like margin="0,0,100,0"

WPF Modal Window Transparency

I have created a modal WPF window that looks as follows:
Here is the code for the window:
<Window x:Class="Dionysus.Core.Controls.ModalWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="ModalWindow" AllowsTransparency="True" Background="Transparent" WindowStyle="None">
<Grid Name="MainGrid">
<Rectangle Fill="Gray" Opacity="0.7" />
</Grid>
The "ErrorControl" is then added as follows:
MainGrid.Children.Add(uc);
The problem is as soon as I expand the stack trace, the controls transparency also changes:
I am assuming this has something to do with the ScrollViewer that uses the incorrect transparency, ie of the Rectangle instead of the containing Window.
I have also set the Opacity of the UserControl which owns the ScrollViewer to 1 and then binded the Opacity:
<ScrollViewer Background="WhiteSmoke" Opacity="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}, Path=Opacity}">
Can anyone help me?
--
UPDATE
Here is the code for the UserControl that is inserted into the Window
<Grid x:Name="LayoutRootx" Background="WhiteSmoke">
<StackPanel VerticalAlignment="Stretch">
<TextBlock TextWrapping="Wrap" Margin="5" Text="An error has occured:" Foreground="Black" FontSize="15" FontWeight="Medium"/>
<TextBlock TextWrapping="Wrap" Margin="5,10,5,5" Text="{Binding Error}"/>
<odc:OdcExpander Header="Stack Trace" Margin="5" IsExpanded="False" Background="WhiteSmoke">
<TextBox Text="{Binding StackTrace}" TextWrapping="Wrap" Margin="5,10,5,5" IsReadOnly="True" MaxHeight="370"/>
</odc:OdcExpander>
<odc:OdcExpander Header="Comment" Margin="5" IsExpanded="False">
<TextBox Text="{Binding Comment}" TextWrapping="Wrap" Margin="5,10,5,5" MaxHeight="370" Name="txtComment"/>
</odc:OdcExpander>
<StackPanel Margin="5,10,5,5" Orientation="Horizontal" HorizontalAlignment="Left">
<Button Style="{StaticResource DionysusButton}" Width="100" Height="23" IsDefault="True" Name="btnSendError">
<StackPanel Orientation="Horizontal">
<Image Source="/Dionysus.Shell;component/Images/camera-icon.png" Margin="0,0,5,0">
</Image>
<TextBlock Text="Send to IT" VerticalAlignment="Center"/>
<core:DionysusTriggerAction Height="0" Width="0" TargetControl="{Binding ElementName=btnSendError}" MethodName="SendError"></core:DionysusTriggerAction>
</StackPanel>
</Button>
<Button Style="{StaticResource DionysusButton}" Width="100" Height="23" Name="btnExit" Margin="10,0,0,0" IsCancel="True">
<StackPanel Orientation="Horizontal">
<Image Source="/Dionysus.Shell;component/Images/DeleteRed.png" Margin="0,0,5,0">
</Image>
<TextBlock Text="Close" VerticalAlignment="Center"/>
</StackPanel>
</Button>
<core:DionysusTriggerAction Height="0" Name="triggerAction2" Width="0" TargetControl="{Binding ElementName=btnExit}" MethodName="Exit"></core:DionysusTriggerAction>
</StackPanel>
</StackPanel>
</Grid>
If your window has a fixed size and cannot be resized, you can use the following trick:
<Grid>
<Border BorderThickness="100" BorderBrush="Gray" Opacity="0.7">
<Grid Background="White" Grid.Column="1" Grid.Row="1" x:Name="contentPlaceHolder">
<TextBlock Text="HELLO WORLD" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Border>
</Grid>
However, it is unlikely that your Window will always have the same size, so to make it more dynamic, you could change the layout of the Window as follows:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="YourDesiredSize"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="YourDesiredSize"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle Fill="Gray" Opacity="0.7" Grid.Row="0" Grid.ColumnSpan="3"/>
<Rectangle Fill="Gray" Opacity="0.7" Grid.Row="2" Grid.ColumnSpan="3"/>
<Rectangle Fill="Gray" Opacity="0.7" Grid.Row="1" Grid.Column="0"/>
<Rectangle Fill="Gray" Opacity="0.7" Grid.Row="1" Grid.Column="2"/>
<Grid Grid.Column="1" Grid.Row="1" Background="White" x:Name="contentPlaceHolder">
<TextBlock Text="HELLO WORLD" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
</Grid>
The result of this window placed on top of another looks more or less like this:
and then instead of adding to the MainGrid, add the UserControl to the contentPlaceHolder or however you want to call it:
contentPlaceHolder.Children.Add(uc);
Okay so I found a solution that works for me, I'm sure it's not the best but it might help someone having the same problem as I did.
The problem was that controls within my UserControl that I added to my Window were transparent, although I could not figure out the reason, I found a simple workaround.
By changing the OpacityMask property of the UserControl to whatever the required Background colour is, even if the controls opacity changes, it will be masked with the Brush that you supply.
uc.OpacityMask = Brushes.WhiteSmoke;
Hope it helps someone!

WPF unexpected control unload

I'm developing a WPF application using MVVM. Inside a Window, I have a control that inherits from UserControl, lets call it DetailView.
DetailView is binded to a property in the VM (CurrentDetail) that can be of different types, UserDetail, AccountDetail, CalendarDetail, etc. All inherit from the same class
I have a "ThumbnailBar" in which I can navigate between different detail instances that have been already opened, imagine AccountDetail1, AccountDetail2, etc.
This navigation is handled updating CurrentDetail in the VM and with the OnPropertyChanged event
The problem comes when I switch from one type (AccontDetail3 for example) to another different type (UserDetail6). I have noticed it calls the "Unloaded" event of the control I'm leaving and the control I'm going to is Initialized, both things don't happen when I navigate through instance of the same type
This causes me some problems, like in calendar where I have a telerik RadScheduler that wont keep the date I had navigated to and reload with the today date.
I know and I have already tested, I could save the variable SelectecTimeSlot and keep reloading it, but that would be just a patch
EDIT - some code:
Here is MainView.xaml where I call CurrentDetailsWorkSpace
<Border x:Name="BorderExteriorContent" BorderBrush="Transparent" BorderThickness="0"
Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="2">
<ContentControl
x:Name="DetalleContenidoWrkSpc"
Background="Red"
Height="{Binding ElementName=BorderExteriorContent,Path=ActualHeight}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Content="{Binding CurrentDetailsWorkSpace}"
VerticalAlignment="Top" Panel.ZIndex="1" />
</Border>
And here is CalendarView (one of the views That unloads) and yes I'm using DataTemplates
<base:BaseUCView
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:base="clr-namespace:MRWTINT.HGC.Win.Views.Base"
mc:Ignorable="d"
xmlns:calVm="clr-namespace:MRWTINT.HGC.Win.ViewModels.Calendario"
x:Class="MRWTINT.HGC.Win.Views.Calendario.CalendarioView"
xmlns:draganddrop="clr-namespace:MRWTINT.HGC.Win.ViewModels.DragDropLib"
xmlns:Calendario="clr-namespace:MRWTINT.HGC.Win.Themes.Calendario"
Margin="0"
d:DesignWidth="730" Height="Auto"
Unloaded="BaseUcViewUnloaded">
<Border x:Name="border" Margin="0,0,30,0" BorderBrush="#FF8A8A8A" BorderThickness="1" CornerRadius="3" RenderTransformOrigin="0.5,0.5">
<Border.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Border.RenderTransform>
<Grid >
<Grid Background="White" Grid.IsSharedSizeScope="True">
<Grid.Resources>
<DataTemplate x:Key="DayWeekSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="20" MinWidth="800" />
</DataTemplate>
<DataTemplate x:Key="AllDaySlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="44" MinWidth="800" />
</DataTemplate>
<DataTemplate x:Key="MonthSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="120" MinWidth="120" />
</DataTemplate>
<DataTemplate x:Key="TimeLineSlotTemplate">
<Border Background="Black" Opacity="0.1" MinHeight="800" MinWidth="110" />
</DataTemplate>
<Calendario:TimeSlotTemplateSelector
x:Key="TimeSlotTemplateSelector"
MonthSlotTemplate="{StaticResource MonthSlotTemplate}"
TimeLineSlotTemplate="{StaticResource TimeLineSlotTemplate}"
AllDaySlotTemplate="{StaticResource AllDaySlotTemplate}"
DayWeekSlotTemplate="{StaticResource DayWeekSlotTemplate}"
/>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<telerik:RadBusyIndicator x:Name="busyIndicator"
Grid.Row="1" BusyContent="{DynamicResource LBL_DetalleCalendario}"
IsBusy="{Binding IsBusy}" Background="{x:Null}" BorderBrush="{x:Null}"
DisplayAfter="{Binding BusyIndicatorDelayedDisplay}">
<telerik:RadScheduler x:Name="scheduler"
TimeSlotTemplateSelector="{StaticResource TimeSlotTemplateSelector}"
draganddrop:DragDropHelper.IsDropTarget="true"
Margin="0"
Grid.Row="1"
FirstDayOfWeek="Monday" FontFamily="Arial" FontSize="10.667"
AppointmentsSource="{Binding ActividadesView}"
calVm:CalendarioEventBehaviours.CalendarioCreateActividadCommand="{Binding SaveCommand}"
calVm:CalendarioEventBehaviours.CalendarioAddActividadCommand="{Binding AddNewActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioDeleteActividadCommand="{Binding DeleteActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioEditingActividadCommand="{Binding EditingActividadCommand}"
calVm:CalendarioEventBehaviours.CalendarioEditedActividadCommand="{Binding EditedActividadCommand}"
telerik:StyleManager.Theme="{DynamicResource RadSchedulerTheme}"
ToolTip="{DynamicResource LBL_ToolTip_Calendario_Generico}"
VerticalContentAlignment="Stretch" HorizontalContentAlignment="Stretch"
ShowsConfirmationWindowOnDelete="False"
OpenModalDialogs="True" Height="Auto"
AllDayAreaHeight="0"
ViewMode="{Binding CalendarioViewMode, Mode=OneWayToSource}">
<telerik:RadScheduler.MonthViewDefinition >
<telerik:MonthViewDefinition />
</telerik:RadScheduler.MonthViewDefinition>
<telerik:RadScheduler.DayViewDefinition >
<telerik:DayViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.DayViewDefinition >
<telerik:RadScheduler.TimelineViewDefinition >
<telerik:TimelineViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.TimelineViewDefinition>
<telerik:RadScheduler.RenderTransform >
<TransformGroup >
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</telerik:RadScheduler.RenderTransform>
<telerik:RadScheduler.WeekViewDefinition >
<telerik:WeekViewDefinition DayStartTime="07:00:00" />
</telerik:RadScheduler.WeekViewDefinition>
<VisualStateManager.CustomVisualStateManager>
<VisualStateManager />
</VisualStateManager.CustomVisualStateManager>
</telerik:RadScheduler>
</telerik:RadBusyIndicator>
<!-- BOTONES PARTE SUPERIOR CALENDARIO -->
<Grid x:Name="Botonera" Margin="10,4,0,0" RenderTransformOrigin="0.5,0.5" Grid.Column="0" HorizontalAlignment="Left" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<!-- REFRESCAR CALENDARIO -->
<StackPanel Grid.Column="0" x:Name="PanelRefresh" Orientation="Horizontal" Cursor="Hand">
<Image x:Name="imgResfresh"
Width="16" Height="16" Source="..\..\Resources\Calendario\table_refresh.png" />
<Button x:Name="btnRefresh"
Content="{DynamicResource BTN_Refrescar}"
Style="{StaticResource ButtonStyle}"
Background="{x:Null}" FontFamily="Arial"
FontSize="10.667" Margin="0,0,5,0"
Command="{Binding RefreshCommand}" />
<Image x:Name="imgWeekends" Margin="10,0,0,0"
Width="16" Height="16" Source="..\..\Resources\Calendario\table_row_delete.png" />
<Button x:Name="btnWeekends"
Style="{StaticResource ButtonStyle}"
Background="{x:Null}" FontFamily="Arial"
FontSize="10.667" Margin="0,0,5,0"
Command="{Binding RefreshCommand}" />
</StackPanel>
<!-- /REFRESCAR CALENDARIO -->
</Grid>
<!-- /BOTONES PARTE SUPERIOR CALENDARIO -->
</Grid>
</Grid>
</Border>
Here the extract of AccountView where I'm using DataTemplates too
<DataTemplate x:Key="ImgContactoTemplate">
<Image RenderOptions.BitmapScalingMode="NearestNeighbor"
Width="16" Height="16" Margin="0,1,0,0" Source="pack://application:,,,/Resources/Cuentas/user.png" />
</DataTemplate>
<DataTemplate x:Key="ImgOportunidadTemplate">
<Image x:Name="imgTipoOportunidadEtapa"
Width="16" Height="16"
RenderOptions.BitmapScalingMode="NearestNeighbor"
Source="{Binding IDTipoEtapa, Converter={StaticResource valueToImageConverter}, ConverterParameter=EtapaOportunidadMini}"
VerticalAlignment="Center" HorizontalAlignment="Center" />
</DataTemplate>
<DataTemplate x:Key="BtCellDataTemplate">
<Button x:Name="btnNewActivityFromOportunidad" Margin="0" Width="20" Height="20" Background="Transparent" Cursor="Hand"
Command="Cuentas:CuentaViewModel.NewActivityFromOportunidadCommand"
CommandParameter="{Binding IDOportunidad}" Padding="0"
VerticalAlignment="Center" HorizontalAlignment="Center"
Visibility="{Binding CanUserCreateNew}"
Style="{DynamicResource ButtonStyle}">
<Image RenderOptions.BitmapScalingMode="NearestNeighbor" Width="16" Height="16"
Margin="0" Source="pack://application:,,,/Resources/Calendario/calendar_add.png" />
</Button>
</DataTemplate>
So using different DataTemplates for every type forces the unloading, that makes sense, any idea to solve that?
EDIT - I have DataTemplates.xaml with DataTemplate for each type in a ResourceDictionary, example:
<DataTemplate DataType="{x:Type vmCal:CalendarioBusquedaViewModel}">
<viewsCalendario:CalendarioBusquedaView Width="Auto" MaxWidth="Infinity"/>
</DataTemplate>
Related posts I've already read:
In wpf, is there a way to execute code before the control is unloaded...? like maybe an unloading event?
How to preserve control state within tab items in a TabControl
If you want to keep state across itemdetails you should put the state in something else than the UserControls that are used to display itemdetails.
It is quite normal that the usercontrol (and thus its state) is unloaded when a different type and corresponding usercontrol is loaded.
So the patch you are suggesting is more or less a correct solution.

Resources