What is the different between 'conv:' and 'local:'? - wpf

Sometimes I see this format:
<UserControl.Resources>
<local:NotConverter x:Key="notConverter" />
</UserControl.Resources>
and sometimes the following:
<TextBlock.Resources>
<conv:IsNullConverter x:Key="isNullConverter"/>
</TextBlock.Resources>
What is the different between "local:" and "conv:" in these two examples?
What other options can I use? (I remember that I saw also "style:")
Thanks.

"Local" and "Conv" are just friendly names for namespaces referenced in your XAML.
You should have the definitions of these keywords at the beginning of your class, something like this:
<View x:Class="MyProject.Views.MyView"
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:conv="clr-namespace:Namespace.Converters"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
x:Name="MyClass"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
So you could use the keyword "conv" to access your converters being in the namespace "Namespace.Converters".
Of course, you could change the name "conv" to whatever name you are comfortable with.

Related

Can I get rid of xmlns tags (and maybe also resources) from my all user controls by using style/resource?

I would like to get rid of xmlns tags from every UserControl or Window file.
Can I do it by using styles or resources somehow?
Many of my user controls look like this:
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
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:bcp="clr-namespace:ABitOfBinding"
xmlns:dc="clr-namespace:Mst2.Dictionaries"
xmlns:vm="clr-namespace:Mst2.ViewModel"
xmlns:vc="clr-namespace:Mst2.ValueConverters"
xmlns:c="clr-namespace:Mst2.View.Controls"
xmlns:mw="clr-namespace:Mst2.View.Windows"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<dc:Mst2Dictionaries x:Key="Dictionaries" />
<bcp:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<vc:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</UserControl.Resources>
<!-- user control contents here -->
</UserControl>
If you instantiate resources from a specific namespace, it has to be declared. How would the parser know which type you are referring to? However, if these resources are located in a separate assembly, you can create a custom XAML namespace and map all of your CLR namespaces to it. This does not work if the resources and namespaces are defined in the same assembly.
Mapping CLR Namespaces to XML Namespaces in an Assembly
Add an XmlnsDefinition attribute for each CLR namespace with your desired XML namespace.
Specifies a mapping on a per-assembly basis between a XAML namespace and a CLR namespace, which is then used for type resolution by a XAML object writer or XAML schema context.
The XmlnsDefinitionAttribute takes two parameters: the XML/XAML namespace name, and the CLR namespace name. More than one XmlnsDefinitionAttribute can exist to map multiple CLR namespaces to the same XML namespace.
You need to insert the attribute at assembly level, so you have to own or be able to modify it.
This attribute, XmlnsDefinitionAttribute, is placed at the assembly level in the source code that produces the assembly.
For example for your Mst2 assembly, the attributes in AssemblyInfo.cs could look like below. You are free to choose the URI, it does not have a special meaning here beyond being an identifer.
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.Dictionaries")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.ViewModel")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.ValueConverters")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.View.Controls")]
[assembly: XmlnsDefinition("http://schemas.Mst2.com/2021", "Mst2.View.Windows")]
Additionally, you could define an XmlPrefix which is a hint to the designer to use this prefix when adding the XAML namespace to your XAML file.
[assembly: XmlnsPrefix("http://schemas.Mst2.com/2021", "mst2")]
Please note that this is respected by designers like in Visual Studio, but others might not.
Identifies a recommended prefix to associate with a XAML namespace for XAML usage, when writing elements and attributes in a XAML file (serialization) or when interacting with a design environment that has XAML editing features.
XAML processors or frameworks that incorporate XAML, or any process that performs XAML serialization, should generally honor the recommended prefix.
When consuming the namespace in your control (in a different assembly), it would look like this.
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
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:mst2="http://schemas.Mst2.com/2021"
xmlns:bcp="clr-namespace:ABitOfBinding"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<mst2:Mst2Dictionaries x:Key="Dictionaries" />
<mst2:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<mst2:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</UserControl.Resources>
<!-- user control contents here -->
</UserControl>
Another thing you could do is to create a resource dictionary for shared resources, e.g.:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:bcp="clr-namespace:ABitOfBinding"
xmlns:dc="clr-namespace:Mst2.Dictionaries"
xmlns:vc="clr-namespace:Mst2.ValueConverters">
<dc:Mst2Dictionaries x:Key="Dictionaries" />
<bcp:ByteBit2Bool x:Key="ByteBit2Bool" />
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<vc:TimerTimeAndRangeConverter x:Key="TimerTimeAndRangeConverter"/>
</ResourceDictionary>
Then you can include it everywhere you need it without having to specify the namespace for each resource or redeclaring the resources each time.
<UserControl x:Class="Mst2.View.Controls.Modules.TimerEntryControl"
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:bcp="clr-namespace:ABitOfBinding"
xmlns:vm="clr-namespace:Mst2.ViewModel"
xmlns:mw="clr-namespace:Mst2.View.Windows"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<BooleanToVisibilityConverter x:Key="BoolToVis" />
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="MySharedResources.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<!-- User control contents here -->
</UserControl>
If these are common resources you could also simply add them to the application resource dictionary, then they would be available in each control, without any further ado.

XAML Syntax for Resource Double value

I'd like to define a static resource to be used for FontSize for multiple items, but I'd like to apply it to the page in which I'm defining it, so I have:
<Page x:Class="Sample1.JoggingPage"
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:core="clr-namespace:System;assembly=mscorlib"
xmlns:local="clr-namespace:Sample1">
<Page.Resources>
<ResourceDictionary>
<core:Double x:Key="MainFontSize">28</core:Double>
</ResourceDictionary>
</Page.Resources>
<Page.FontSize>
What do I have to do here to use MainFontSize as the value??
</Page.FontSize>
I have tried everything I can think of and searched for a related answer, but I obviously don't have the important keywords to search for this.
Thank you in advance,
Chris

XAML Namespace Beginning with a Number

I have inheritted Button and am trying to add it to my main window.
It doesn't show up in the Toolbox. I have tried rebuilding several times.
I have tried adding xmlns:dc="clr-namespace:123Letters and xmlns:dc="clr-namespace:123Letters;assembly=123Letters to my MainWindow.
My MainWindow is:
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Name="MainWin"
Title="123 Letters">
</Window>
My WeatherStationButton is:
<Button x:Class="WeatherStationButton"
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"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
</Grid>
</Button>
and
Public Class WeatherStationButton
Inherits Button
Public Property WeatherStation As tblWeather
End Class
This is super simple stuff. I believe it's because XAML doesn't allow numbers in the first part of namespaces, but I can not find any reference to that anywhere, so I am asking if I am doing something wrong or is this one of XAML's "features"?
Just realized I could add my answer.
If your project name is 123Letters, you need to add an underscore before the first number when referencing it in XAML like, _123Letters.
Your clr-namespace declaration would then be:
xmlns:dc="clr-namespace:_123Letters"
and you could add your inherited button to your MainWindow like this:
<dc:WeatherStationButton x:Name="btnWS" />

Create Design Time Data in WPF

My MainWindow.xaml loads very slowly, so I'm trying to create a design-time data for that. I have checked some websites on the net and tried to create design-time data but it gives error.
Here is my part of xaml, the rest is wpf elements :
<Window x:Class="CodeFirstMVVM.App.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:cm="clr-namespace:System.ComponentModel;assembly=System"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:CodeFirstMVVM.App.ViewModels"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="clr-namespace:CodeFirstMVVM.App.ViewModels"
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=model:Ogrenci, IsDesignTimeCreatable=True}"
DataContext="{Binding Source={StaticResource Locator}, Path=OgrenciView}"
Title="MainWindow" Height="500" Width="900">
I get the error in this line :
d:DataContext="{d:DesignInstance Type=model:Ogrenci, IsDesignTimeCreatable=True}"
And the errors are :
Error 1 The namespace prefix "model" is not defined.
Error 2 Ogrenci is not supported in a Windows Presentation Foundation (WPF)
The DesignTimeViewModel is under CodeFirstMVVM.App, and it is simply an empty class with an empty constructor. Can you tell me how to create a design time data in a healthy way? I'm really stuck with this.

XAML namespace naming conventions

I have a C# WPF project, namespaced test. How should I name sub-namespaces in XAML?
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test"
xmlns:local.c="clr-namespace:test.Converters"
xmlns:local.v="clr-namespace:test.Validators"
Title="MainWindow" Height="360" Width="640"> ....
Here I have a convention of separating the sub-packages with a period.. Is it okay?
Kind regards,
e.
A better practice, if possible, would be to separate the C# namespaces that you use from the WPF namespaces. This will also reduce the number of imports that you have. This can be done thanks to the XmlnsDefinition class.
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:test="http://whatever.com/test">
In the AssemblyInfo.cs of your libraries, you'll just need to add:
[assembly: XmlnsDefinition("http://whatever.com/test", "test")]
[assembly: XmlnsDefinition("http://whatever.com/test", "test.Converters")]
[assembly: XmlnsDefinition("http://whatever.com/test", "test.Validators")]
[assembly: XmlnsDefinition("http://whatever.com/test", "test.CustomControls")]
Note that this will only work if the classes are in a different assembly to the one you are referencing them from. Within the same assembly, you'll still need to use the C# namespaces.
You can even eliminate the imports altogether by adding your namespaces to the WPF XML namespace:
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "test")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "test.Converters")]
[assembly: XmlnsDefinition("http://schemas.microsoft.com/winfx/2006/xaml/presentation", "test.Validators")]
That allows people to write:
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<!-- Note: no namespace prefix needed! -->
<YourCustomControl />
The typical WPF application really doesn't have a namespace convention for the XAML, other than the default xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml", the Blend design time namespace and xmlns:local which will typically refer to the current namespace.
In the scenario you described above, I've seen/used a few variants, i.e.,
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test"
xmlns:c="clr-namespace:test.Converters"
xmlns:v="clr-namespace:test.Validators">
or
<Window x:Class="test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:test"
xmlns:conv="clr-namespace:test.Converters"
xmlns:val="clr-namespace:test.Validators">
In the end, it's really up to whatever you and your team agree upon.

Resources