Поделиться через


Presentation.More

In the same vein as System.More, I've also created a Windows Presentation Foundation counterpart called Presentation.More.  And just like System.More defines classes in the same System namespaces as System.dll and System.Core.dll, Presentation.More also defines classes in the System.Windows namespaces directly.  Not only does this work elegantly for code-based languages like C# and VB, but it also works in XAML by simply adding XmlnsDefinitionAttributes to the Presentation.More assembly.  So far I have classes in six different namespaces under System.Windows, so I have a file called XmlnsDefinitions.cs in my Presentation.More project that looks like this (the ... dots are just because the blog is not wide enough to show the full string):

 using System.Windows.Markup;

[assembly: XmlnsDefinition("https://schemas.microsoft.com/winfx/2006/xaml/presentation", "System.Windows")]
[assembly: XmlnsDefinition("https://schemas.microsoft.com/.../presentation", "System.Windows.Controls")]
[assembly: XmlnsDefinition("https://schemas.microsoft.com/.../presentation", "System.Windows.Data")]
[assembly: XmlnsDefinition("https://schemas.microsoft.com/.../presentation", "System.Windows.Documents")]
[assembly: XmlnsDefinition("https://schemas.microsoft.com/.../presentation", "System.Windows.Input")]
[assembly: XmlnsDefinition("https://schemas.microsoft.com/.../presentation", "System.Windows.Media")]

For example, one of the classes is a NineGridImage which lives in namespace System.Windows.Controls.  Without XmlnsDefinitionAttributes, your application's XAML would have to declare the namespace and use it everywhere you wanted to use the control:

 <Window x:Class="WpfApplication1.Window1"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:more="clr-namespace:System.Windows.Controls;assembly=Presentation.More">
    <more:NineGridImage Source="..."/>
</Window>

But by adding the XmlnsDefinition attribute to the Presentation.More assembly for the System.Windows.Controls namespace above you can use a NineGridImage just like you'd use any other built-in control:

 <Window x:Class="WpfApplication1.Window1"
        xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml">
    <NineGridImage Source="..."/>
</Window>

Some may think this is confusing or even unethical, but I think it makes the resulting application code clearer and more elegant.  I don't suggest overriding the System namespaces for every class, especially when a class is specific to a particular application.  But for classes that have nothing to do with a particular client application and "should have been in System.dll" or "should have been in PresentationFramework.dll", I think it's best to treat them as part of the framework rather than bring attention to yet another namespace.