Adding .cs in a ResourceDictionary? - c#

I have DataTemplate in a ressource dictionnary, and in some, I need button and i don't know how i can use code behind for manage events.
I tried to put a class in my resource dictionnary like that :
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SLProject.Templates"
x:Class="TVTemplate">
And I definied the class in the cs file like that :
namespace SLProject.Templates
{
partial class TVTemplate
{
}
}
The build is OK but when the application started, I obtains XAML error following :
AG_E_PARSER_BAD_TYPE
I tried all I know like change the class kind to a ClassModifier, make the class to an inherited class of RessourceDictionnary ... no way.
Someone have an idee ...
Thanks.

Using the x:Class attribute allows you to define a codebehind for a ResourceDictionary.
You must specify the complete namespace of the class (i.e. x:Class="WpfApplication.MyClass"), and such class has to be defined as partial (at least VS 2010 complains and does not compile without such modifier).
I mocked-up a simple example:
1. Create a new WPF application project (WpfApplication)
2. Add a new class file (TestClass.cs) and paste the following code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows;
namespace WpfApplication
{
public partial class TestClass
{
private void OnDoubleClick(object obj, MouseButtonEventArgs args)
{
MessageBox.Show("Double clicked!");
}
}
}
3. Add a new ResourceDictionary (Resources.xaml), open the file and paste the following code
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication.TestClass">
<Style TargetType="{x:Type Label}">
<EventSetter Event="Label.MouseDoubleClick" Handler="OnDoubleClick"/>
</Style>
</ResourceDictionary>
4. Finally, open the MainWindow.xaml and past the following code
<Window x:Class="WpfApplication.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>
<ResourceDictionary Source="Resources.xaml"/>
</Window.Resources>
<Grid>
<Label Content="Double click here..." HorizontalContentAlignment="Center" VerticalContentAlignment="Center" Background="Red"/>
</Grid>
</Window>
In the example I wire-up a double-click event from a Style, since it is a scenario requiring you to call some code from a ResourceDictionary.

You have the x:Class attribute defined twice, which is why you're getting the parser error. Change your declaration to this and it should work:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SLProject.Templates.TVTemplate">

I Checked, and it's just an error of copy-past. I have well the class definied one time.

Best thing would be to make your own usercontrol and add your events in it . and later put this entire usercontrol in resource dictionary.

Related

cannot reference WPF controls in code-behind in a different page

I made a project where it was one page only, then after I made everything decided to go back in and make a second page, which was a huge mistake because now I have 50 compiler errors. In my new page's code behind, I cannot access any control by name and the page cannot access any event handlers in the code-behind. Here is an example:
Autoclicker.xaml
<Page x:Class="_1337clicker.Pages.Autoclicker"
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:_1337clicker.Pages"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800"
Title="Autoclicker">
<Grid>
<Button Name="hi"/>
</Grid>
</Page>
Autoclicker.xaml.cs
using System.Windows;
using System.Windows.Controls;
namespace _1337clicker
{
public partial class Autoclicker : Page
{
public Autoclicker()
{
hi.Content = "hello world"; //The name "hi" does not
//exist in the current context
}
}
}
I think you just messed up classname/namespace.
Check in XAML:
x:Class="_1337clicker.Pages.Autoclicker"
This will generate all the variables related to controls in a class called Autoclicker in a namespace of _1337clicker.Pages
but then, your code-behind class is:
namespace _1337clicker // <---- DIFFERENT NAMESPACE
{
public partial class Autoclicker : Page
You ended up with two 'Autoclicker' classes, one generated from XAML, other writen by you. Correct the namespaces and class names so they are identical, and try again. Generated code will end up in the same class as codebehind, and probably all such errors will go away.
EDIT: also what Joe noticed, it should be x:Name. Just 'Name' will let you find the control with tree walking and/or find-by-name tools, but probably won't generate a variable for code-behind.

Generic Window-Classes

I want to have a generic type of a Window.
However, if I implement the <R> into the class definition, it gives me errors, everywhere I reference on the xaml, e.g. at InitializeComponent(); or if I want to access any label or button.
The name 'InitalizeComponent' is not available in the current context
Probably, the reference/linking from the xaml to the code behind does not work properly.
Are there any suggestions, how I can achieve a correct linking to the xaml with generic window classes?
C#
namespace MyNamespace
{
public partial class Designer<R> : Window, IEventListener
where R : Region, new()
{
...
}
}
XAML
<Window
x:Class="MyNamespace.Designer"
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:local="clr-namespace:MyNamespace"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Title="Designer"
Width="1600"
Height="1000"
mc:Ignorable="d">
...
</Window>
You need to provide x:TypeArguments directive:
<Window
x:Class="MyNamespace.Designer"
x:TypeArguments="src:Region"
...
</Window>

WPF generic.xaml could not find file

I have some custom converters for my wpf dialog.
All of sudden i get this message:
The Name "BoolToVisibilityInversConverter" is in the Namespace "clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog" not available
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:conv="clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog">
<conv:BoolToVisibilityInversConverter x:Key="btvInvConv"/>
<conv:TimeSpanConverter x:Key="timeConv"/>
<conv:BoolToVisibilityConverter x:Key="btvConv"/>
<conv:BoolInversConverter x:Key="BoolInversConverter"/>
</ResourceDictionary>
A class as Example:
namespace plans.SeqOpDialog.Converter
{
public class BoolToVisibilityInversConverter : IValueConverter
{...
}}
I cleaned the project, restarted VS and i'm out of ideas what i could do
Did you miss the Converter?
xmlns:conv="clr-namespace:plans.SeqOpDialog.Converter;assembly=plans.SeqOpDialog.*Converter*">

Using UserControl as base class in wpf is showing empty

Hello I am using Prism in my demo project and I have a problem with user controls' inheritance. If I use my user control base class for my user control like below, user control's content is showing up empty. Then when I use
<igf:UserControlBase x:Class="DemoProject.Views.DemoView"
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:igf="http://igf.schema"
mc:Ignorable="d" d:DesignWidth="300" d:DesignHeight="200">
<StackPanel>
<TextBox Text="Hello Prism"/>
<TextBlock Text="Hello Prism"></TextBlock>
</StackPanel>
</igf:ViewControlBase>
and this is my user control and it is in another project. And ctors are commented now but still not working. Only way is changing
using System.Windows;
using System.Windows.Controls;
namespace DemoProject.Base.Controls
{
public class UserControlBase : UserControl
{
static UserControlBase()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(UserControlBase), new FrameworkPropertyMetadata(typeof(UserControlBase)));
}
public UserControlBase()
{
DefaultStyleKey = typeof(UserControlBase);
}
}
}
I found solution by adding code below into Assembly.cs file to user control's project
[assembly: ThemeInfo(ResourceDictionaryLocation.None, ResourceDictionaryLocation.SourceAssembly)]

Styling all instances of a derived type in WPF

I have a class named MyWindow that derives from Window:
using System.Windows;
public class MyWindow : Window
{
}
And I use that class in MainWindow.xaml:
<MyWpfApp:MyWindow x:Class="MyWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:wpfApplication1="clr-namespace:WpfApplication1"
Title="MainWindow" Height="350" Width="525">
<Grid>
<TextBlock Text="Test" Foreground="Orange"/>
</Grid>
</MyWpfApp:MyWindow>
And in the App.xaml file, I add the following style to override the Background property of all MyWindow instances:
<Application.Resources>
<Style TargetType="MyWpfApp:MyWindow">
<Setter Property="Background" Value="Black"></Setter>
</Style>
</Application.Resources>
But this doesn't change anything at all. No style is applied to MainWindow.
What should I do so that I can use a global style for all MyWindows?
P.S.: I checked out "Modern UI"s code, I saw that they apply something like the following in their window's constructor:
using System.Windows;
public class MyWindow : Window
{
public MyWindow()
{
DefaultSyleKey = typeof (MyWindow);
}
}
But if I do this, MainWindow ends up being completely black in the content area. I am guessing that somehow its Template property gets overriden, but I don't understand how, and how to make this work.
Ok I have worked it out. Apparently there's a special file you can use named generic.xaml.
You need to add your style definitions there and then add that file to a directory called Themes.
WPF will end up using that as a fall back: Themes\generic.xaml

Categories