⬆️ ⬇️

WPF Markup Extensions

With the release of .Net 3.0, we have the opportunity to supplement the base classes without redefining them with our own methods. This technology is called Code Extensions Methods

But as it turned out, using the same simple and very flexible method, you can expand the capabilities and XAML layouts of windows and components.



A simple example of the use of an extension is the familiar construction.

< Button Content ="{Binding Path=Title}" />



* This source code was highlighted with Source Code Highlighter .


Where Binding is nothing more than language extensions.

And now a specific example correcting the lack of the above construction, when you can only bind to yourself through a long line of code

< Button Content ="{Binding Path=Height,

RelativeSource={RelativeSource Self}}"
/>




* This source code was highlighted with Source Code Highlighter .


Create your own SelfBinding extension:

1. Add a class to the project and call it SelfBinding

2. Inherit this class from MarkupExtension

3. Add the Path property of type string

4. Create an empty constructor

5. Create a constructor with a single parameter string Path

public SelfBinding( string Path)

{

this .Path = Path

}




* This source code was highlighted with Source Code Highlighter .


6. Override its method ProvideValue

public override object ProvideValue(IServiceProvider serviceProvider)

{

try

{



if ( string .IsNullOrEmpty(Path))

throw new ArgumentNullException( "Path" , "The Path can not be null" );



// ,

var providerValuetarget = (IProvideValueTarget)serviceProvider

.GetService( typeof (IProvideValueTarget));



// ,

DependencyObject _targetObject = (DependencyObject)providerValuetarget.TargetObject;



//

PropertyInfo _sourceProperty = _targetObject.GetType().GetProperty(Path);



//

return _sourceProperty.GetValue(_targetObject, null );



}

catch (Exception ex)

{

Debug.WriteLine(ex);

return null ;

}

}




* This source code was highlighted with Source Code Highlighter .




Now you can and check

< Window x:Class ="for7raid.wpfExtension.Window1"

xmlns ="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

xmlns:x ="http://schemas.microsoft.com/winfx/2006/xaml"

xmlns:local ="clr-namespace:for7raid.wpfExtension"

Title ="Window1" Height ="300" Width ="300" >



< Grid >

< Button Content ="{local:SelfBinding Foreground}" />

</ Grid >

</ Window >




* This source code was highlighted with Source Code Highlighter .


Everything turned out, now you should add the ability to use converters, as is done in the standard Binding.

7. Add a converter like IValueConverter and check it when returning the result

// ,

if (Converter != null )

return Converter. Convert ( value , _targetProperty.PropertyType, null ,

Thread.CurrentThread.CurrentCulture);

else

return value ;




* This source code was highlighted with Source Code Highlighter .




Everything!

')

Well, for a snack: import into the standard namespace our Namespase so that each time we do not have to write the prefix before each extension. Add the following line to the Assembly.cs file and select the project

[assembly: XmlnsDefinition( "http://schemas.microsoft.com/winfx/2006/xaml/presentation" , "for7raid.wpfExtension" )]



* This source code was highlighted with Source Code Highlighter .




TODO:

1. Add a property change trigger so that there is a live binding

2. It is possible to implement the task path in the following form: Path = Foreground.Name



Some problems can be solved this way, for example, we have built support for multilingualism, as well as a manager who has been watching the display of elements on the form, depending on the user's rights.



< Button Content ="{Title btnKey, Default=Hello button}" ,

Visability ="{AllowedBy All sp1 sp2 sp3}" />




* This source code was highlighted with Source Code Highlighter .




Source Code



Read on: Markup Extensions and XAML

WPF Multilanguage Markup Extension

Source: https://habr.com/ru/post/84263/



All Articles