MVVM Change properties of views placed in another view - c#

I'm having a problem with setting properties of a View that is placed in a Grid of my MainView. Specifically it's a TreeView explorer for which I want to implement a button that hides it and at the same time sets the ColumnSpan of another view that is next to this one to span on all of the columns. My XAML looks like this:
<UserControl x:Class="ImageViewer.View.MainView"
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:local="clr-namespace:ImageViewer.View"
xmlns:model="clr-namespace:ImageViewer.ViewModel"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.DataContext>
<model:MainViewModel/>
</UserControl.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="62*"/>
<!--<ColumnDefinition Width="0.1*"/>-->
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="195*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<local:FileExplorerView x:Name="fileExplorerView" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,0.333">
<local:FileExplorerView.Style>
<Style TargetType="{x:Type local:FileExplorerView}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding FileExplorerVisibility}" Value="Collapsed">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</local:FileExplorerView.Style>
</local:FileExplorerView>
<local:TiledWindowView Margin="0,0,1,0.333">
<local:TiledWindowView.Style>
<Style TargetType="{x:Type local:TiledWindowView}">
<Setter Property="Grid.ColumnSpan" Value="1"/>
<Setter Property="Grid.Column" Value="2"/>
<Style.Triggers>
<DataTrigger Binding="{Binding FileExplorerVisibility}" Value="Collapsed">
<Setter Property="Grid.ColumnSpan" Value="4"/>
<Setter Property="Grid.Column" Value="0"/>
</DataTrigger>
</Style.Triggers>
</Style>
</local:TiledWindowView.Style>
</local:TiledWindowView>
</Grid>
<local:MainMenuView Grid.Row="0"/>
<local:FooterView Grid.Row="2"/>
</Grid>
In MainViewModel I invoke OnPropertyChange method and I am 100% sure that it works properly because I tested it with replacing the view with a single TextBlock and I was able to change its properties in XAML using DataTrigger for the same property - FileExplorerVisibility.
I know that there was plenty of entries on this forum about DataTriggers however I could find no answer that answers my problem, none of them work for me. I have never had any problem with finding solutions however this time I even had to create an account to create my first question.
Has anyone any idea what is wrong with this code? Or maybe another approach that I am not aware of would be better in this situation?
MainViewModel
private Visibility fileExplorerVisibility = Visibility.Visible;
public Visibility FileExplorerVisibility {
get => fileExplorerVisibility;
set
{
fileExplorerVisibility = value;
NotifyPropertyChanged();
}
}
public MainViewModel()
{
_aggregator.GetEvent<CollapseEvent>().Subscribe(Collapse);
}
public void Collapse()
{
FileExplorerVisibility = Visibility.Collapsed;
}
FileExplorerViewModel
public RelayCommand CollapseCommand { get; set; }
public FileExplorerViewModel()
{
CollapseCommand = new RelayCommand(CollapseExecute, CollapseCanExecute);
}
private void CollapseExecute(object obj)
{
_aggregator.GetEvent<CollapseEvent>().Publish();
//Task.Run(() => CollapseMethod());
}
private bool CollapseCanExecute(object obj)
{
return true;
}
So the user presses the button in FileExplorerView then the CollapseEvent is published, the MainViewModel subscribes for that event and executes a particular method. I checked this part many times and it works fine. I think the problem is in somewhere in the XAML.

Ok, I have found a solution. Maybe it is not the best one but it works. I simply placed those views in Grids inside particular columns of a Grid level above and I set the properties of these Grids without manipulating the views. Is this a common practice or there exist a better solution?
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="10*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="62*"/>
<!--<ColumnDefinition Width="0.1*"/>-->
<ColumnDefinition Width="40*"/>
<ColumnDefinition Width="195*"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Grid.ColumnSpan="2" Margin="0,0,0,0.333">
<Grid.Style>
<Style TargetType="{x:Type Grid}">
<Setter Property="Visibility" Value="Visible"/>
<Style.Triggers>
<DataTrigger Binding="{Binding FileExplorerVisibility}" Value="Collapsed">
<Setter Property="Visibility" Value="Collapsed"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Grid.Style>
<local:FileExplorerView/>
</Grid>
</Grid>
Evk, Thank You very much for pointing out that the DataContext may be wrong, it helped me a lot.

Related

Parse Exception occurring due to my Styling

I am creating a WPF application in C# using XAML. I have looked into the documentation of creating Styles for XAML.
It looks to be working correctly in the Designer before I actually run my application. Upon running my application I receive a parse exception. Looking at the line and position indicated, <Style="{StaticResource T}" /> is the cause of this error. Removing it solves the issue, but this requires me to do an inline Style which I would like to avoid.
The XAML code for the Page encountering this issue is below and I would appreciate any feedback and guidance on this issue. The Style not working here is the x:Key="T" TargetType="Border".
<Page x:Class="NGClient1.Screen1.BE2.WindowBe2Tablet"
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:local="clr-namespace:NGClient1.Screen1.BE2"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="WindowBe2Tablet" Width="1024" Height="1280" Background="Black">
<Grid>
<Grid>
<Grid.ColumnDefinitions >
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Image Source="Resources/backdrop.png" Stretch="UniformToFill" Grid.ColumnSpan="2" Grid.RowSpan="3" />
<StackPanel Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="2" Grid.RowSpan="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Advert Section Here" />
</StackPanel>
<Border Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" BorderBrush="White" BorderThickness="4" Background="Black" Margin="40, 40, 40, 40" Opacity="0.5"/> -->
<Border Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Style="{StaticResource T}" /> <!-- Exception being thrown here, unsure why -->
<StackPanel Grid.Column="0" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Lower Section Left Here" />
</StackPanel>
<StackPanel Grid.Column="1" Grid.Row="2" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock Text="Lower Section Right Here" />
</StackPanel>
</Grid>
</Grid>
<Page.Resources>
<Style x:Key="T" TargetType="Border" > <!-- x:Key causing exception, unsure why -->
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="BorderThickness" Value="4"/>
<Setter Property="Background" Value="Black"/>
<Setter Property="Margin" Value="40, 40, 40, 40"/>
<Setter Property="Opacity" Value="0.5"/>
</Style>
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="25"/>
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
</Style>
</Page.Resources>
</Page>
When using StaticResources, the order of defining and referencing a resource in XAML matters.
Provides a value for any XAML property attribute by looking up a reference to an already defined resource. Lookup behavior for that resource is analogous to load-time lookup, which will look for resources that were previously loaded from the markup of the current XAML page as well as other application sources, and will generate that resource value as the property value in the run-time objects.
As stated in the documentation for static resource lookup:
Forward references cannot be resolved by a static resource reference.
In your case, the resource section is at the bottom of the page, so the resource will be defined after it is first referenced through StaticResource. In order to solve the issue, you have to either move the resources section to a position before resources defined within it are referenced or use DynamicResource instead.
<Border Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2" Style="{DynamicResource T}"/>
The DynamicResource Markup Extension instead processes a key by creating an expression, and that expression remains unevaluated until the app runs, at which time the expression is evaluated to provide a value.

Convert static XAML inline styles to external CSS style sheet

To start I am not familiar with XAML however I know XML/CSS exceptionally well. I've begun helping a friend add some style to their XAML application though very quickly noticed that all of their styling is inline which is a nightmare. Here is a good chunk of their code:
add-type -AssemblyName System.Windows.Controls.Ribbon, PresentationFramework
[xml]$xaml = #"
<Window Height="425" Title="TSD-Essentials" Width="1050" x:Name="Window" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:ribbon="clr-namespace:System.Windows.Controls.Ribbon;assembly=System.Windows.Controls.Ribbon" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:z="http://www.w3.org/1999/xhtml">
<Grid x:Name="Grid">
<Grid.RowDefinitions>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
<RowDefinition Height="AUTO"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="75"/>
<ColumnDefinition Width="155"/>
<ColumnDefinition Width="AUTO"/>
<ColumnDefinition Width="AUTO"/>
<ColumnDefinition Width="AUTO"/>
<ColumnDefinition Width="AUTO"/>
</Grid.ColumnDefinitions>
<Grid.Background>
<LinearGradientBrush StartPoint=".5,0" EndPoint=".5,1">
<GradientStop Color="White" Offset="0"/>
<GradientStop Color="#52618f" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<Label Content="Host Name:" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Width="80" />
<TextBox x:Name = "HostName" Grid.Column="1" Grid.Row="0" HorizontalAlignment="Left" Width="150"></TextBox><!--Enter host name-->
<Label Content="Service Now:" Grid.Column="2" Grid.Row="0" />
<TextBox Grid.Column="3" Grid.Row="0" Width="175" x:Name = "SNtextBox">Search ServiceNow</TextBox>
</Grid>
</Window>
"#
$reader = (New-Object System.Xml.XmlNodeReader $xaml)
$window = [Windows.Markup.XamlReader]::Load($reader)
$window.ShowDialog()
Now I've attempted to research and add my own style sheet declarations...
External:
<StyleSheet Source="styles.css" />
Internal:
<StyleSheet>
<![CDATA[
TextBox {background-color: #f0f;}
]]>
</StyleSheet>
However I keep getting error messages. The XAML documentation I come across has various elements such as application however my friend is using window. So I don't know if there is versioning involved or not hence why I pasted a large snippet of the code I've begun to clean up.
Exception calling "Load" with "1" argument(s): "Cannot create unknown type '{http://schemas.microsoft.com/winfx/2006/xaml/presentation}StyleSheet'."
I've been reading through documents like the following though all I end up getting are error messages:
https://learn.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/styles/css/#xaml
I'm vaguely aware that this is somehow .NET related (using Windows PowerShell ISE to edit this) though I'm not familiar with this. I simply need to help him get out of inline styling or he'll never get any work done. How can I get a style sheet working and with a simple example of how to change the background-color (or whatever XAML equivalent) to define the background-color of all of the TextBox elements?
I'm not entirely sure if there is an efficient manner of doing this however this does work. I added the Window.Resources element just after the Window element. Here is the code for that:
<Window [...]><!-- Shown for it's relative position in the code. -->
<Window.Resources>
<Style TargetType="TextBox">
<Setter Property="Background" Value="#000" />
<Setter Property="Foreground" Value="#ccc" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="FontSize" Value="17" />
</Style>
</Window.Resources>
CSS :hover and :focus style appears to be a subset (trying to use minimal code):
<Window.Resources>
<Style TargetType="TextBox">
<!-- CSS background-color -->
<Setter Property="Background" Value="#000" />
<Style.Triggers>
<!-- CSS :hover -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="#f0f" />
<Setter Property="Background" Value="#222" />
<Setter Property="Foreground" Value="#fff" />
</Trigger>
<!-- CSS :focus -->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter Property="BorderBrush" Value="#f0f" />
<Setter Property="Background" Value="#222" />
<Setter Property="Foreground" Value="#fff" />
</Trigger>
</Style.Triggers>
</Style>
</Window.Resources>

Set Dimensions of RelativePanel's Children proportional to that of parent view

I am new to Windows Runtime programming and decided to get stuck in ahead of the release of Windows 10.
I am trying to design an adaptive page UI that looks something like as follows,
There is header "stuff" at the top and beneath it I want two columns, each with a textblock header and below it, a listview. The listview could be arbitraryheight and so the parent of the two blocks should, I think, be a scrollviewer.
On mobile however, this UI won't work as the screen is far to narrow, and so I would like to use a visualstate to rearrange the page so it looks as follows,
As you can see, the need for a scrollviewer is apparent to wrap this section. the "Other stuff" at the top should stay fixed however so it can be seen all the time.
I have tried a number of approaches to achieve this but haven't been able to manage it. What I currently have is this:
//.... Other Stuff ......
<ScrollViewer x:Name="SummaryScrollViewer" Grid.Row="2" HorizontalScrollBarVisibility="Disabled"
HorizontalScrollMode="Disabled" VerticalScrollMode="Auto" VerticalScrollBarVisibility="Auto" HorizontalContentAlignment="Center">
<RelativePanel x:Name="SummaryRelativePanel">
<Grid x:Name="lCol" Width="{Binding ActualWidth, ElementName=SummaryRelativePanel}">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="lcolHead" Grid.Row="0" Text="TextBlock:"/>
<ListView x:Name="lcolList" Grid.Row="1">
</ListView>
</Grid>
<StackPanel x:Name="rCol" Orientation="Vertical" RelativePanel.RightOf="lCol">
<TextBlock x:Name="rcolHead" Text="TextBlock:"/>
<ListView x:Name="rcolList" Height="Auto">
</ListView>
</StackPanel>
</RelativePanel>
</ScrollViewer>
As you can see, I have tried to make the contents of each column both a stackpanel, and a grid, but I haven't been able to set the width of them to be, in "desktop view", half that of the containing relative panel, which should fill the full width of the screen, and in "mobile view" they should fill the full width of the parent.
I have found answers on how to bind the width to the ActualWidth property of the parent element as can be seen in the snippet, and this works, but I can't seem to make the two columns fill half of the parent each.
I wanted to use a RelativePanel so I can use the viewstate to change the properties of the right hand column to be either RightOf="LeftCol" or Below="LeftCol", and the widths should then be updated too to fill the width required.
Using a grid Should also be possible, define a 4x4 grid where in desktop the bottom two are collapse, or in mobile the right two are collapsed, but I was under the impression that this is the precise usecase the relativepanel was intended for.
In all examples of relativepanel they use relativepanel to move programmer defined with/height elements such as rectangles RelativePanel class.
It would also be possible to manually set ActualWidth of each column programatically from the code-behind but I don't know how to query which visual state the app/page is currently in to figure out how wide and where each column should be.
Any help and advice on what the "best" way to achieve such a thing would be would be greatly appreciated.
Here we go, let's begin that the bugs (or things I think are bugs)
1.- If I set a control with binding to the RelativePanel ActualWidth it just takes the first time, I mean, if I expand the window the control does not resize, so bug?
So let's do it with Grid:
<Grid x:Name="LayoutRoot" Background="Red" >
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="WindowSizeStates" >
<VisualState x:Name="SmallScreen" >
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="0"/>
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ContentLayoutRoot.Background" Value="Green"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[0].Height" Value="100"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[1].Height" Value="400"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[2].Height" Value="100"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[3].Height" Value="400"/>
<Setter Target="ContentLayoutRoot.ColumnDefinitions[0].Width" Value="1*"/>
<Setter Target="ContentLayoutRoot.ColumnDefinitions[1].Width" Value="0"/>
<Setter Target="SubHeaderOneLayout.(Grid.Row)" Value="0"/>
<Setter Target="ContentOneLayout.(Grid.Row)" Value="1"/>
<Setter Target="SubHeaderTwoLayout.(Grid.Row)" Value="2"/>
<Setter Target="ContentTwoLayout.(Grid.Row)" Value="3"/>
<Setter Target="SubHeaderTwoLayout.(Grid.Column)" Value="0"/>
<Setter Target="ContentTwoLayout.(Grid.Column)" Value="0"/>
</VisualState.Setters>
</VisualState>
<VisualState x:Name="WideScreen">
<VisualState.StateTriggers>
<AdaptiveTrigger MinWindowWidth="1000" />
</VisualState.StateTriggers>
<VisualState.Setters>
<Setter Target="ContentLayoutRoot.Background" Value="Purple"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[0].Height" Value="100"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[1].Height" Value="900"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[2].Height" Value="0"/>
<Setter Target="ContentLayoutRoot.RowDefinitions[3].Height" Value="0"/>
<Setter Target="ContentLayoutRoot.ColumnDefinitions[0].Width" Value="0.5*"/>
<Setter Target="ContentLayoutRoot.ColumnDefinitions[1].Width" Value="0.5*"/>
<Setter Target="SubHeaderOneLayout.(Grid.Row)" Value="0"/>
<Setter Target="ContentOneLayout.(Grid.Row)" Value="1"/>
<Setter Target="SubHeaderTwoLayout.(Grid.Row)" Value="0"/>
<Setter Target="ContentTwoLayout.(Grid.Row)" Value="1"/>
<Setter Target="SubHeaderTwoLayout.(Grid.Column)" Value="1"/>
<Setter Target="ContentTwoLayout.(Grid.Column)" Value="1"/>
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<Grid x:Name="HeaderLayout" VerticalAlignment="Top" Height="32">
<TextBlock Text="Other Stuff" HorizontalAlignment="Center"/>
</Grid>
<ScrollViewer Grid.Row="1">
<Grid x:Name="ContentLayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="900"/>
<RowDefinition Height="0"/>
<RowDefinition Height="0"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.5*"/>
<ColumnDefinition Width="0.5*"/>
</Grid.ColumnDefinitions>
<Grid x:Name="SubHeaderOneLayout" >
<TextBlock Text="Sub Header One" HorizontalAlignment="Center"/>
</Grid>
<Grid x:Name="SubHeaderTwoLayout" Grid.Column="1">
<TextBlock Text="Sub Header Two" HorizontalAlignment="Center"/>
</Grid>
<Grid x:Name="ContentOneLayout" Background="Orange" Grid.Row="1">
<TextBlock Text="ContentOne Layout" HorizontalAlignment="Center"/>
</Grid>
<Grid x:Name="ContentTwoLayout" Background="Orange" Grid.Row="1" Grid.Column="1">
<TextBlock Text="ContentOne Layout" HorizontalAlignment="Center"/>
</Grid>
</Grid>
</ScrollViewer>
I could try to make it with Relative Panel but involves events, and more things, tell me if it is enough.
And, well the triggers I discovered by myself, you can get more info in my article in codeproject

BooleanToVisibilityConverter with checkbox

I am trying to hide the grid, controlled by the checkbox. Currently, when I use the box nothing happens. I cannot figure out why. Everything I have found online is exactly what I have.
<Window.Resources>
<BooleanToVisibilityConverter x:Key="BoolToVis"/>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition />
</Grid.RowDefinitions>
<!--upper window..-->
<CheckBox x:Name="show" Grid.Row="1" IsChecked="False">Display Preview with Sliders?</CheckBox>
<Grid Grid.Row="1"
Visibility="{Binding ElementName=show, Path=isChecked, Converter={StaticResource BoolToVis}}">
<!--what I want to hide-->
</Grid>
</Grid>
It doesn't make any sense.
Property names are case sensitive. Replace isChecked with IsChecked in your binding.
Visibility="{Binding ElementName=show, Path=IsChecked,
Converter={StaticResource BoolToVis}}"
Try
Path=IsChecked
Even XAML is case-sensitive.
I advice to use a DataTrigger
<Style x:Key="CheckBoxStyle" TargetType="{x:Type CheckBoxStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=show,Path=IsChecked,}" Value="False">
<Setter Property="Visibility" Value="Collapsed"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>

WPF Resource overriding

I have a question regarding styles in xaml wpf.
I have a Default style which should apply for all Objects. But for some of them I want to set a second style overriding a few attributes.
Now if I give my second style a x:key="style2" and set this as style, my first Default style is not applied, but the Default WPF style is. I can not/want not Change anything at my first Default style
How can I fix this behaivor?
To ensure that your default style is still applied, you add
BasedOn={StaticResource ResourceKey={x:Type ControlType}}
Where ControlType is the type of object the default style was applied to.
Here's an example:
<Window x:Class="StyleOverrides.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">
<Window.Resources>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="FontFamily" Value="Comic Sans MS" />
</Style>
<Style x:Key="Specialization"
TargetType="{x:Type TextBlock}"
BasedOn="{StaticResource ResourceKey={x:Type TextBlock}}"
>
<Setter Property="FontStyle" Value="Italic" />
<Setter Property="Foreground" Value="Blue" />
</Style>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Viewbox Grid.Row="0" >
<TextBlock>This uses the default style</TextBlock></Viewbox>
<Viewbox Grid.Row="1">
<TextBlock Style="{StaticResource Specialization}">
This is the specialization
</TextBlock>
</Viewbox>
</Grid>
</Window>

Categories

Resources