I have problems with accessibility to a class, from the MainWindow code behind.
I have written this class:
namespace WpfApp1.Management
{
public class BookManagement : INotifyPropertyChanged
{ ...
which is referenced in MainWindow:
<Window
x:Class="WpfApp1.MainWindow"
x:Name="mainWindow"
...
xmlns:mangmt="clr-namespace:WpfApp1.Management"
by:
<Window.Resources>
<mangmt:BookManagement x:Key="bookManagement" />
</Window.Resources>
the fact is that I need to access to bookManagement from MainWindow.cs, and I tried this:
BookManagement bm= Application.Current.Resources["bookManagement"] as BookManagement;
bm.SelectedTab = "summary";
but I get a null reference exception at runtime.
thank you.
It is part of your MainWindow's resources, not part of the application:
<Window.Resources>
<mangmt:BookManagement x:Key="bookManagement" />
</Window.Resources>
Use this to retrieve it instead:
Application.Current.MainWindow.Resources["bookManagement"]
Related
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>
I am having a problem with the Visual Studio designer for a WPF project and the combination of binding to a type using a generic and specifying a nullable type as the generic type.
I have tried to construct a minimal example of the problem:
XAML:
<Window x:Class="TestWpfApp.MainWindow"
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:local="clr-namespace:TestWpfApp"
mc:Ignorable="d" d:DataContext="{d:DesignInstance local:TestViewModel}"
Title="MainWindow" Height="450" Width="800">
<Grid>
<TextBlock Text="{Binding TestText.Value}"/>
<!--<TextBlock Text="{Binding TestTextValue}"/>-->
</Grid>
</Window>
Code behind:
using System.Windows;
namespace TestWpfApp
{
public class TestGeneric<T>
{
public TestGeneric(T value)
{
Value = value;
}
public T Value { get; }
}
public class TestViewModel
{
public TestGeneric<double?> TestText { get; } = new TestGeneric<double?>(123.456);
public double? TestTextValue => TestText.Value;
}
public partial class MainWindow : Window
{
public MainWindow()
{
DataContext = new TestViewModel();
InitializeComponent();
}
}
}
The designer fails with this code with the following error message:
System.Runtime.Remoting.RemotingException
[16040] Designer process terminated unexpectedly!
The commented out line in the XAML code does not give the error in the designer window.
Both versions actually work when running the project. It is only the designer that fails.
Does anyone have any idea about what the problem could be?
The d:DataContext design time expression is a very practical trick, and IDE related, it has no impact on the runtime, only affect the design time. Applicable in Visual Studio 2010 and later.
The default constructor is required for a type to be instantiated in XAML.
The option IsDesignTimeCreatable=True tells the designer that it can create the specified class via default constructor. This way it is possible to provide sample data for the UI.
d:DataContext="{d:DesignInstance local:TestViewModel , IsDesignTimeCreatable=True }"
Yong Lu
I've created an class which will be the DataContext for my app, and instantiated it via XAML:
<Window x:Class="MyApp.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:myDataModel="clr-namespace:MyApp.MyDataModel"
Title="MainWindow">
<Window.Resources>
<myDataModel:MyDataClass x:Name="the_DataModel" x:Key="a_DataModel"/>
</Window.Resources>
I want to act on this object in the constructor of my Window:
public MainWindow()
{
InitializeComponent();
the_DataModel.LoadFromFile(); // One of these *should* work!
a_DataModel.LoadFromFile();
}
However it seems that neither name (the_DataModel, nor a_DataModel) is a member of the Window class. When I type this., and use auto-complete, I cannot find anything that resembles the object I created in XAML.
How can I create an instance of a class in XAML, and access it in code?
Since you have added it as a resource in window resources, you can get it from Resource collection by indexing with resource key.
MyDataClass dataModel = (MyDataClass)Resources["a_DataModel"];
dataModel.LoadFromFile();
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
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.