WPF Class Library with custom control - control won't show - c#

After a couple of hours searching the web, I turn to you all:
My WPF class library (.NET 3.5, COM visible) has a form in it, which uses an UserControl and a theme file.
The problem:
When using WPF Applications, the buttons work just fine, but in this .NET 3.5, COM Visible, class library, they won't show at all. Other objects from the library can be used and work.
What could be the problem? I'm leaning towards the resource dictionary that can't be found, or some of the resources that cannot be found, but I can't put my finger on it.
Any help would be most welcome!
Some code
The resources are set via the
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MyLibrary;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
There we place - for now - a simple:
<Grid>
<lib:ImageButton ImageSource="/MyLibrary;component/Images/some_image.png" />
</Grid>
Not forgetting the reference for the library in the project and the xamls:
xmlns:lib="clr-namespace:MyLibrary;assembly=MyLibrary"
The MyLibrary holds this ImageButton - a simple button extension mainly to hold an image.
The WPF looks somewhat like:
<UserControl x:Class="MyLibrary.ImageButton"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:lib="clr-namespace:MyLibrary"
x:Name="me"
Width="auto"
Height="22"
HorizontalAlignment="Center" VerticalAlignment="Center">
<UserControl.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type library:ImageButton}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="False">
<Setter Property="Width" Value="22" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="True">
<Setter Property="Width" Value="auto" />
</DataTrigger>
</Style.Triggers>
</Style>
</ResourceDictionary>
</UserControl.Resources>
<Button x:Name="_button" Click="Button_Click" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Width="auto">
<StackPanel Orientation="Horizontal">
<Image Source="{Binding ElementName=me, Path=ImageSource}" Stretch="Uniform" />
<TextBlock x:Name="_Text" Text="{Binding ElementName=me, Path=Text}" VerticalAlignment="Center" Margin="2, 0, 0, 0">
<TextBlock.Resources>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
<DataTrigger Binding="{Binding ElementName=me, Path=HasText}" Value="True">
<Setter Property="Visibility" Value="Visible" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Resources>
</TextBlock>
</StackPanel>
</Button>
</UserControl>
The .cs side is fairly arbitrary I guess.
Finally, we have Generic.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/MyLibrary;component/Themes/MyTheme.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
Where "MyTheme" holds lots of templates, colours etc..

The problem most likely stems from the fact that your Class Library project has no idea that there are resource dictionaries you want to consume everywhere even though you merged your resource dictionaries in some file. The reason for this is that Visual Studio and Blend both look for an ApplicationDefinition file for global resource dictionaries to consume.
Class Library projects cannot have ApplicationDefinition files. However, there is a way you can share resources for design time viewing of your custom control project. A question on that topic and the answer can be found here (disclaimer: the link currently points to my answer).
Please take note that if you use the solution linked to above, you will still have to reference your resource dictionaries at the App.xaml level of any Application project that consumes your class library as your class library will not contain the specific styling..

Well this question is rather old but here goes:
After doing a lot of comparison i verified that the way to get it working is setting the following lines somewhere in your class library on the assembly level:
[assembly: ThemeInfo(
ResourceDictionaryLocation.None,
ResourceDictionaryLocation.SourceAssembly
)]

Related

C# WPF Button Styles inside DLL

I'm making a DLL for me, to ease my job, because there are classes that I use in every project, so why should i duplicate them, when I can use one DLL to finish the job,
I also wanted to add some controls to it, buttons, so its like this:
I have created a button, and it works well, but I want to add a custom style to it, to disable the background highlighting when you are mouse over, now i have used this style before and works well, but in previous times, I would add the style to the app.xaml resources and then set the style to the button like:
Style="{StaticResource DisableBackgroundHighlight}"
but since the DLL does not have app.xaml, what should I do, how to add style to the control inside the DLL?
All I've found on google was, to reference the resources from the DLL to the app.xaml of the WPF app, but thats not what I want,
I tried this:
<Button x:Class="SRX.Windows.Controls.SRXButton"
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:SRX.Windows.Controls"
mc:Ignorable="d"
d:DesignHeight="35" d:DesignWidth="100" Content="OK" Background="White" BorderBrush="Blue" Foreground="Blue" MouseEnter="Button_MouseEnter" MouseLeave="Button_MouseLeave" Style="{StaticResource DisableBackgroundHighlight}">
<Button.Resources>
<Style x:Key="DisableBackgroundHighlight" TargetType="Button">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="Cursor" Value="Hand" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="border" BorderThickness="0" BorderBrush="Black" Background="{TemplateBinding Background}">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Opacity" Value="0.8" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Resources>
but it doesnt work, it shows "The resource "DisableBackgroundHighlight" could not be resolved." altough it compiles but crashes on startup.
If I missed something in the problem explanation please ask me to resolve, thanks in advance.
Simply add a xaml file to your project. Let's call it Generic.xaml which is where usually the templates for your custom coltrols will be located .
This file will have the following format:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Your.Domain.Generic">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="whatever else you defined in another xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="TextBox" ....
</ResourceDictionary>
on the other assemblies, you import your "style" assembly just like anything else:
xmlns:style="clr-namespace:Your.Domain.Shared"
Supposing of course that you style assembly is named Your.Domain.Shared

UWP Style in a nested ItemsController not working

I have a User Control that works in the sense that it displays the data that it needs to display, the issue I have is the the style doesn't appear to be working in the most inner ItemsControl.
The style is working on the outer ItemsControl, which kind of has me stumped.
App.Xaml
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Dictionaries/StyleDictionary.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
UserControl.xaml
<ItemsControl ItemsSource="{x:Bind Cat.Content}">
<ItemsControl.ItemTemplate>
<DataTemplate >
<StackPanel>
<TextBlock Text="{Binding Header}" Style="{StaticResource myStyleTextBlock_Header}" />
<ItemsControl ItemsSource="{Binding Body}">
<DataTemplate>
<StackPanel>
<TextBlock Style="{StaticResource myStyleTextBlock_Paragraph}" Text="{Binding Body}"/>
</StackPanel>
</DataTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
I was reading something about styles being encapsulated within User Controls, but if the outer style in the template works why does the second one not get applied.
Edit:
Maybe I should try to explain what I am trying to do and someone can suggest a better way.
Right now I have a class that has something like this.
public class Content
{
public string Header { get; set; }
public List<string> Body { get; set; }
}
And the user control is them just
<UIControls:DisplayDossierText />
The style is very simple, it is just styling a textbox to have colors and margins etc.
<Style TargetType="TextBlock" x:Key="myStyleTextBlock_PageHeader">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="FontSize" Value="30" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="Margin" Value="0,0,25,15" />
<Setter Property="Foreground" Value="#007bb8" />
</Style>
<Style TargetType="TextBlock" x:Key="myStyleTextBlock_Paragraph" BasedOn="{StaticResource myStyleTextBlock_Header}">
<Setter Property="TextWrapping" Value="Wrap" />
<Setter Property="Margin" Value="0,5,15,30" />
<Setter Property="FontSize" Value="16" />
<Setter Property="Foreground" Value="#ff00063e" />
</Style>
So the idea is that the control displays the header, the the collection of body in the style. As state above, the header is styled fine, but the body text has no style applied to it at all.
I have been trying to find a good solution to this, best way to approach it and found nothing. So playing around I cam up with what I have at the moment, but I feel that this is probably not the best solution to what I am trying to achieve.
There is currently no Code Back for this, but the normal shell of code created when creating the control.
Anyway, I am getting the suspicion that I need to be going in a different direction and not really sure how to go about this. All examples I find are based on styling a control with the basics of a button or listview. While listview is kind of what this is, it will not be interactive. It's main purpose is to provide an easy way to change paragraphs of text and store it in a database and then pull it up and display it.
Anyone?

ContentControl Rotate decorator rendering

I have recently stumbled upon following issue: In my WPF application I've implemented a little designer, where you can put elements on canvas, move, scale and rotate them.
While searching the web I found following solution to this problem . This solution implements moving, scaling and rotating by System.Windows.Controls.Primitives.Thumb class so I thought I would just adjust this solution to my app and move on. The problem is, while on my machine everything is fine, on the others there are some rendering problems. I've made a screen shot of what I'm saying:
I'm using Windows 7 even though I run my app on other Windows 7 and it is also rendered wrong. I run my app with Windows XP and other compatibility settings on my machine but I wasn't able to reproduce this bug. What is this about and what am I possibly doing wrong?
This is my xaml file I'm using for content control styling:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:COMPANY.WPUI.LayoutDesignModel.Thumbs">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MoveThumb.xaml"/>
<ResourceDictionary Source="ResizeDecorator.xaml"/>
<ResourceDictionary Source="RotateDecorator.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="DesignerItemStyle" TargetType="ContentControl">
<Setter Property="MinHeight" Value="50"/>
<Setter Property="MinWidth" Value="50"/>
<Setter Property="RenderTransformOrigin" Value="0.5,0.5"/>
<Setter Property="SnapsToDevicePixels" Value="true"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<Grid DataContext="{Binding RelativeSource={RelativeSource TemplatedParent}}">
<Control Name="RotateDecorator" Template="{StaticResource RotateDecoratorTemplate}" Visibility="Collapsed"/>
<s:MoveThumb Template="{StaticResource MoveThumbTemplate}" Cursor="SizeAll"/>
<Control x:Name="ResizeDecorator" Template="{StaticResource ResizeDecoratorTemplate}" Visibility="Collapsed"/>
<ContentPresenter Content="{TemplateBinding ContentControl.Content}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="Selector.IsSelected" Value="True">
<Setter TargetName="ResizeDecorator" Property="Visibility" Value="Visible"/>
<Setter TargetName="RotateDecorator" Property="Visibility" Value="Visible"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
A this is RotateDecorator.xaml file that happens to cause problems:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:COMPANY.WPUI.LayoutDesignModel.Thumbs">
<Style TargetType="{x:Type s:RotateThumb}">
<Setter Property="Cursor" Value="Hand"/>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type s:RotateThumb}">
<Grid Width="30" Height="30">
<Ellipse Width="30" Height="30" Fill="#B0B0BB" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<ControlTemplate x:Key="RotateDecoratorTemplate" TargetType="{x:Type Control}">
<Grid>
<s:RotateThumb Margin="-18,-18,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"/>
<s:RotateThumb Margin="0,-18,-18,0" VerticalAlignment="Top" HorizontalAlignment="Right" />
<s:RotateThumb Margin="0,0,-18,-18" VerticalAlignment="Bottom" HorizontalAlignment="Right" />
<s:RotateThumb Margin="-18,0,0,-18" VerticalAlignment="Bottom" HorizontalAlignment="Left" />
</Grid>
</ControlTemplate>
</ResourceDictionary>
The first thing I think of whenever seeing something like this is the graphics cards. You can get some strange behaviors with certain graphics cards, especially if their drivers are not installed properly/up to date.
This is caused by MergedDictionaries. The Diagram Designer Project splits the Move, Resize, and Rotate actions into 3 separate dictionaries. From the screenshot you can see the resize thumb is loaded. In my case the move action also worked, but like the question the rotate thumbs weren't displayed. No errors were thrown, but examination with Snoop shows that it wasn't able to find the rotate dictionary.
This solution expands on what I've covered above: https://stackoverflow.com/a/17083360/978622
To solve: Combine the resource dictionaries into a single resource dictionary.

Why can't I get the custom font from the resources?

I have a library where contains a ThemeResources file, where contain styles.
In Fonts folder, I have a font file BuxtonSketch.ttf. Build Action is as RESOURCE
In ThemeResources, I've defined the font:
<FontFamily x:Key="FontFamily-Sketch">pack://application:,,,/Resources/Fonts/#Buxton Sketch</FontFamily>
<Style x:Key="TextNormalStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="{StaticResource FontFamily-Sketch}" />
</Style>
And since my UserControl called ProblemUserControl, I invoked but is not working
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/ThemeResources.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<TextBlock Text="La pelicula PROMETHEUS!" Style="{StaticResource TextNormalStyle}" />
</Grid>
What could be happening?
This blog and this blog both use the following syntax to use a custom font
Blog 1:
<TextBlock Text="SOTC Custom Fonts!" FontFamily="VINERITC.TTF#Viner Hand ITC"/>
blog2:
<TextBlock Text="Gothic" FontFamily="./GOTHIC.TTF#Century Gothic"/>
So for you I would think it would be
<TextBlock Text="Buxton" FontFamily="BuxtonSketch.TTF#Buxton Sketch"/>
Or for your style
<Style x:Key="TextNormalStyle" TargetType="TextBlock">
<Setter Property="FontFamily" Value="BuxtonSketch.TTF#Buxton Sketch" />
</Style>
You may need to include the folder location, but not sure
<TextBlock Text="Buxton" FontFamily="Resources/Fonts/BuxtonSketch.TTF#Buxton Sketch"/>
Also you can add the fonts to .zip file and access like this:
<Setter Property="FontFamily" Value="../Resources/Fonts/Fonts.zip#BuxtonSketch"/>
I just spent a whole day researching this problem. When copying the fonts into the project, make sure Visual Studio set the Build Action of these items to Resource. All I had to do was change this in the dropdown.

Using usercontrols with static resources from external assembly

It sounds very simple and it's killing me!
I'm trying to use one usercontrol with styles from a ResourceDictionary of an external assembly, but I get an exception at runtime.
Here is how to reproduce:
Create a silverlight class library called MyControls.dll
Create an usercontrol called SuperControl:
<UserControl.Resources>
<ResourceDictionary Source="MyControls;component/Styles.xaml" x:Key="Styles" />
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
<TextBlock Style="{StaticResource MyStyle}" Text="Hello"/>
</Grid>
Create a Styles.xaml ResourceDictionary and add:
<Style x:Key="MyStyle" TargetType="TextBlock">
<Setter Property="FontSize" Value="15"/>
<Setter Property="FontWeight" Value="Bold"/>
<Setter Property="TextWrapping" Value="Wrap"/>
<Setter Property="Margin" Value="0,15,0,4"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
</Style>
Create a Silverlight Application Called SL and add Mycontrols as reference
In MainPage.xaml Grid, add:
<MyControls:SuperControl />
It will compile, but running the application you get "Failed to assign to property 'System.Windows.ResourceDictionary.Source'. [Line: 10 Position: 36]"
I added this to the application's App.xaml
<ResourceDictionary Source="/MyControls;component/Styles.xaml" />
Same error... :(
Any thoughts?
Step 2.
You forgot /.
Source="MyControls;component/Styles.xaml"
Write
Source="/MyControls;component/Styles.xaml"

Categories

Resources