WPF baml serialization bug? - c#

The following XAML produces XamlParseException in runtime:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib">
<Grid>
<Grid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary>
<TextBlock x:Key="{x:Type TextBlock}">
<Run Text="Aaaa"/>
</TextBlock>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<sys:String x:Key="aaa"></sys:String>
</ResourceDictionary>
</Grid.Resources>
<Border Child="{StaticResource {x:Type TextBlock}}"/>
</Grid>
</Window>
XamlParseException: 'Missing key value on 'TextBlock' object.' Line number '10' and line position '20'.
What am I doing wrong?

Keys can't be types, they're strings.

Related

ResourceDictionary is not used as button style

I am trying to use ResourceDictionary to set up a style for a button
<Window.Resources>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
<ResourceDictionary x:Key="ButtonStyle"> //If I don't use key it gives error
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
and using it as
<Button Style="{DynamicResource ButtonStyle}"/>
Now, when I do this it complains that ResourceDictionary can not be applied to Style. When I use "GlassButton" as defined in GlassButton.xaml it says that GlassButton could not be resolved.
when I use it like
<Button Style="{StaticResource ButtonStyle}"/>
or use GlassButton in both cases either it complains or wont work.
GlassButton.xaml looks like this, and compiling fine
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Citations">
<Style x:Key="GlassButton" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="42" />
<Setter Property="Foreground" Value="White" />
<Setter Property="Template">
I am taking this example from here or here both are kind of using same approach of using ResourceDictionary. I am doing as shown but it still not working. Do I need a converter for this? or I am doing something wrong?
The following worked for me. Check that the path to GlassButton.xaml is correct. If you put it in a folder such as Styles you would need to use Source="Styles/GlassButton.xaml".
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Button Style="{DynamicResource GlassButton}"
Content="Button Content"/>
</Grid>
I should be using it as follows
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
</ResourceDictionary>
</Window.Resources>
This worked
Move the
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
line to inside of ResoruceDictonary like below:. Then you don't need to enter the key x:Key="ButtonStyle" and then style will be applied
<Window.Resources>
<ResourceDictionary >
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="GlassButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<vieModel:MainWindowViewModel x:Key="MainViewModel"/>
</ResourceDictionary>
</Window.Resources>

Resource Dictionary not working - Exception raised for Name/Key not found

I have just started working with Resource Dictionaries and I am stuck on this because my resource dictionary is not working at all. I have tried code-behind and XAML but every time I get exceptions and the app crashes.
If I reference the Dictionary through XAML I get the exception at runtime that Name/Key is not found. The code I used in App.xaml is:
<Application
x:Class="WatchfreeWebsite.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WatchfreeWebsite.Helpers">
<Application.Resources>
<TransitionCollection x:Key="TransCollection">
<EdgeUIThemeTransition Edge="Right"/>
</TransitionCollection>
<ResourceDictionary x:Key="resourcesDictionary">
<ResourceDictionary.MergedDictionaries>
<local:GlobalTemplates Source="Helpers/GlobalTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
The resource dictionary holds aDataTemplate and a MediaTransportControlsStyle but I cant seem to reference it through XAML because it gives syntax errors and during the runtime the page produces exception while loading XAML at InitializeComponent(); stage.
Resource Dictionary:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:WatchfreeWebsite.Helpers"
x:Class="WatchfreeWebsite.Helpers.GlobalTemplatesClass"
xmlns:data="using:WatchfreeWebsite.Helpers">
<DataTemplate x:Key="StreamBoxItemTemplate"
x:DataType="data:StreamingHelper">
<TextBlock Text="{x:Bind StreamName, Mode=OneWay}"
Style="{StaticResource BodyTextBlockStyle}"
TextWrapping="NoWrap"
MaxLines="1"
TextTrimming="WordEllipsis"/>
</DataTemplate>
<Style TargetType="MediaTransportControls"
x:Key="myCustomTransportControls">
<Setter Property="IsTabStop" Value="False" />
.......
</Style>
</ResourceDictionary>
The class behind the resource dictionary is:
public partial class GlobalTemplatesClass
{
public GlobalTemplatesClass()
{
this.InitializeComponent();
}
}
I reference the DataTemplate inside the above style and this style is referenced in another page as:
<MediaPlayerElement x:Name="MediaView"
Grid.Row="2"
Source="{Binding MediaSourceObject, Mode=OneWay}"
DoubleTapped="MediaView_DoubleTapped"
AreTransportControlsEnabled="True">
<MediaPlayerElement.TransportControls>
<data:CustomTransportControlsHelper Style="{StaticResource ResourceKey=myCustomTransportControls}"/>
</MediaPlayerElement.TransportControls>
</MediaPlayerElement>
But this is not working and there is a red line below the resource name saying that the resource is not found.
Is there something that I am missing? If someone can help me here please provide your suggestions. Thanks
When you add multiple items under your resources, each of them should fall within the <ResourceDictionary> tag and not directly under <Application.Resources>.
That's because Resources itself is a dictionary, so you're in effect trying to replace that collection rather than add elements to it. Docs here: https://msdn.microsoft.com/en-us/library/system.windows.application.resources%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
I created a sample project with just an App.xaml at the project base level, a folder called Helpers and a ResourceDictionary under Helpers named GlobalTemplates.xaml to match yours.
Created a simple brush as an example in GlobalTemplates.xaml
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1.Helpers">
<SolidColorBrush x:Key="DefaultForeground" Color="DarkGreen" />
</ResourceDictionary>
In App.xaml
<Application
x:Class="App1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
RequestedTheme="Light">
<Application.Resources>
<ResourceDictionary>
<TransitionCollection x:Key="TransCollection">
<EdgeUIThemeTransition Edge="Right"/>
</TransitionCollection>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="Helpers/GlobalTemplates.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
And then in MainPage.xaml successfully referenced the style from the dictionary:
<Page
x:Class="App1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:App1"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<TextBlock Foreground="{StaticResource DefaultForeground}">Hello world</TextBlock>
</Grid>
</Page>

Reference one resource from another ResourceDictionary

For example, we have two ResourceDictionary:
Global.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<FontFamily x:Key="GlobalFontFamily">Segoe UI</FontFamily>
</ResourceDictionary>
Part.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ReousrceDictionary Source="Global.xaml" />
</ResourceDictionary.MergedDictionaries>
<FontFamily x:Key="PartFontFamily">**Reference GlobalFontFamily here**</FontFamily>
</ResourceDictionary>
MainWindow.xaml
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary.MergedDictionaries>
<ReousrceDictionary Source="Part.xaml" />
</ResourceDictionary.MergedDictionaries>
</Window.Resources>
<Grid>
<TextBlock FontFamily="{StaticResource PartFontFamily}" />
</Grid>
</Window>
In some view, I would use PartFontFamily to set the element font family. Which I would like to achieve is, use the specified font family when PartFontFamily is set, otherwise use GlobalFontFamily instead. So I want to keep the PartFontFamily key, and reference it to GlobalFontFamily since customers have no specified font family for PartFontFamily.
Any good suggestions?
Merge your Part.xaml to the Global.xaml... so that you can refer every thing from the Global.xaml...
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ReousrceDictionary Source="Part.xaml" />
</ResourceDictionary.MergedDictionaries>
<FontFamily x:Key="GlobalFontFamily">Segoe UI</FontFamily>
Merge the Global.xaml to your MainWindow...
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Window.Resources>
<ResourceDictionary.MergedDictionaries>
<ReousrceDictionary Source="Global.xaml" />
</ResourceDictionary.MergedDictionaries>
</Window.Resources>
<Grid>
<TextBlock FontFamily="{DynamicResource PartFontFamily}" />
</Grid>
</Window>
You can directly access the PartFontFamily here...
I guess you want to make an alias for your resource.
<DynamicResource x:Key="PartFontFamily" ResourceKey="GlobalFontFamily"/>

To call converter from ControlTemplate string

I'm trying to bind controlTemplate to in generic.xaml.My controlTemplate has converter in it.While binding,its throwing an exception as Provide value on 'System.Windows.Markup.StaticResourceHolder' threw an exception.
In MyView.cs
templateString = #"<ControlTemplate xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"" >
<Canvas><Polygon Points=""{Binding Size,Converter={StaticResource SizeConverter}}"" Fill=""red""/></Canvas>
</ControlTemplate>";
this.Template = XamlReader.Load(new System.Xml.XmlTextReader(new StringReader(templateString ))) as ControlTemplate;
In generic.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:src="clr-namespace:MySample"
xmlns:vsm="clr-namespace:System.Windows;assembly=PresentationFramework"
xmlns:srcview="clr-namespace:MySample.Views"
xmlns:converters="clr-namespace:MySample.Converters"
>
<converters:SizeConverter x:Key="SizeConverter" />
<Style TargetType="{x:Type srcview:MyView}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type srcview:MyView}">
<Canvas>
<ContentControl Template="{TemplateBinding Template}" Name="contentControl" >
</ContentControl>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
How to fix this issue??
One normally gets this problem when the static resources are not defined before referencing them.
For a test, try reading an xaml usercontrol with a static resource defined in the resources section of the xaml. If that works then you know the problem is not with referencing the converter, but rather when and were it is defined.
A faster way to ensure that the converter is actually being loaded is to put it in the app.xaml. This will ensure that the resource dictionary is loaded at startup. Here follows an example:
<Application x:Class="TeslaFrame.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:metro="http://schemas.codeplex.com/elysium"
>
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Elysium;component/Themes/Generic.xaml"/>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="globalBoolToVisConverter" />
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

access ResourceDictionary across different projects in solution

How do I access a ResourceDictionary from different project in a solution?
My Solution file contains a few projects. One of these projects is named "Common" and contains a Resource called SharedResource.xaml.
SharedResource.xaml in Common:
<ResourceDictionary 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">
<ImageBrush x:Key="UserIcon" ImageSource="/Images\icon_user.png"/>
</ResourceDictionary>
This is how I tried to make the SharedResource Dictionary usable in one of my UserControls.
<UserControl x:Class="MasterDataManagement.View.DisplayMasterDataView"
xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:command="http://www.galasoft.ch/mvvmlight"
xmlns:common="clr-namespace:Common;assembly=Common"
mc:Ignorable="d"
d:DesignWidth="800" d:DesignHeight="600" d:DataContext="{Binding DisplayMasterDataViewModel, Source={StaticResource ViewModelLocator}}">
<UserControl.Resources>
<ResourceDictionary> <!-- ERROR Each dictionary entry must have an associated key.-->
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/Resources/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<!-- Removed Content -->
</Grid>
</UserControl>
Unfortunately, this approach doesn't work and I'm not sure what I missed. The Code above causes this error message: Each dictionary entry must have an associated key.
Any thoughts?
Notes:
I can't put the ResourceDictionary into App.xaml because I create direct UserControl instances(something like UserControl uc = new DisplayMasterDataView() ).
Only the App.xaml from the Project which is set as StartUp Project is "executed". My solution consists out of one MainProject (which is set as StartUp Project) and a few other projects which are used as modules in the MainProject. Now, I need to use this modules in my MainProject which is done like this:
UserControl uc = new DisplayMasterDataView();
My point is that creating an instance of an UserControl from a different project does not execute the App.xaml in the project which consist the UserControl. Therefore I have to use <UserControl.Resources> </UserControl.Resources> to define my resources.
I just mentioned this because the most sample projects use the App.xaml to define Resources.
Each dictionary entry must have an associated key...
Surely that error is just telling you that you need to add a key to your ResourceDictionary using the x:Key notation... in this case, the 'dictionary entry' is your ResourceDictionary and the 'associated key' is whatever you call it to reference it later, in my example below, 'CommonResourceDictionary':
<ResourceDictionary x:Key="CommonResourceDictionary">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary
Source="pack://application:,,,/Common;component/Resources/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
My WinView project contains a file called ViewResources.xaml in which I place all the resources needed by the controls in that project. It also links in other xaml files in the same project:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MainTabControlStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
<!-- ==================== Data Templates ==================== -->
<DataTemplate DataType="{x:Type myNameSpace:MyViewModel}">
<controls:MyUserControl MyProperty="{Binding ...etc...}" />
</DataTemplate>
</ResourceDictionary>
My main project then references this in App.xaml:
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<!-- Main Theme -->
<ResourceDictionary Source="pack://application:,,,/WPF.Themes;component/BureauBlue/Theme.xaml" />
<!-- Global Resources for Views -->
<ResourceDictionary Source="pack://application:,,,/MyProject.WinView;component/ViewResources.xaml" />
<ResourceDictionary Source="pack://application:,,,/MyProject.WinUI;component/HelpResources.xaml" />
... and so on and so forth ...
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
I don't see how this would stop you from creating UserControls directly.
Here comes the solution, thanks you for pointing me into the right direction Rohit Vats!
Not Working
<UserControl.Resources>
<gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
<telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
<telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
<telerik:RadMenuItem.ItemContainerStyle>
<Style TargetType="telerik:RadMenuItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
<Setter Property="IsCheckable" Value="True" />
</Style>
</telerik:RadMenuItem.ItemContainerStyle>
</telerik:RadMenuItem>
<telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
<telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
</telerik:RadContextMenu>
</gridView:RadContextMenuXamlHolder>
<Style TargetType="telerik:GridViewHeaderCell">
<Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
</Style>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
Working
<UserControl.Resources>
<ResourceDictionary>
<gridView:RadContextMenuXamlHolder x:Key="ContextMenuHolder">
<telerik:RadContextMenu DataContext="{Binding Path=UIElement.Column.DataControl.DataContext, RelativeSource={RelativeSource Self}}" InheritDataContext="False"
StaysOpen="True" x:Name="CellCellContextMenu" Placement="Bottom" Loaded="ContextMenu_OnLoaded">
<telerik:RadMenuItem x:Name="ColumnsMenuEntry" Header="Choose Columns:" ItemsSource="{Binding Path=Menu.UIElement.Column.DataControl.Columns, RelativeSource={RelativeSource Self}}" StaysOpenOnClick="True">
<telerik:RadMenuItem.ItemContainerStyle>
<Style TargetType="telerik:RadMenuItem">
<Setter Property="Header" Value="{Binding Header}" />
<Setter Property="IsChecked" Value="{Binding IsVisible, Mode=TwoWay}" />
<Setter Property="IsCheckable" Value="True" />
</Style>
</telerik:RadMenuItem.ItemContainerStyle>
</telerik:RadMenuItem>
<telerik:RadMenuItem Header="Show all columns" Click="RadMenuItem_ShowAllColumns_OnClick"/>
<telerik:RadMenuItem Header="Hide all columns" Click="RadMenuItem_HideAllColumns_OnClick"/>
</telerik:RadContextMenu>
</gridView:RadContextMenuXamlHolder>
<Style TargetType="telerik:GridViewHeaderCell">
<Setter Property="telerik:RadContextMenu.ContextMenu" Value="{Binding Path=CellContextMenu, Source={StaticResource ContextMenuHolder}}"/>
</Style>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/Common;component/SharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
the trick was to move all resources into the <ResourceDictionary> </ResourceDictionary> tag.

Categories

Resources