The WPF interaction command references a local static resource for the converter

I want to create a reusable control that has a behavior attribute. As described in this blog

To bind data, data must be converted. Problem in; as StaticResourcehe can see only the top-level dictionary ( app), and dynamic resources do not work ("can only be used with the dependency property").

Simple (working) xaml (window):

<Window x:Class="testit.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
                        <i:InvokeCommandAction.CommandParameter>
                            <Binding Path="Name"
                                     Converter="{StaticResource SelectionConverter}"
                                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
                        </i:InvokeCommandAction.CommandParameter>
                    </i:InvokeCommandAction>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
        <TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
    </Grid>
</Window>

applications:

<Application x:Class="testit.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:testit"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <local:SelectionConverter x:Key="SelectionConverter" />
    </Application.Resources>
</Application>

And finally, the viewmodel:

using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows.Data;

namespace testit
{
    class ViewModel : INotifyPropertyChanged
    {
        private string _data;
        private readonly DelegateCommand<string> _mouseEnterCommand = null;

        public ViewModel() {
            _data = "hello ";
            _mouseEnterCommand = new DelegateCommand<string>(
                (s) => {
                    var a = s ?? "world ";
                    Data += s;
                    return;
                });
        }

        public DelegateCommand<string> MouseEnterCommand => _mouseEnterCommand;

        public string Data {
            get { return _data; }
            set {
                if (value == _data) return;
                _data = value;
                OnPropertyChanged("Data");
            }
        }


        public event PropertyChangedEventHandler PropertyChanged;
        protected virtual void OnPropertyChanged(string propertyName) {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    public class SelectionConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
            if (value == null) return "";
            char[] charArray = ((string)value).ToCharArray();
            Array.Reverse(charArray);
            return new string(charArray);
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
            throw new NotImplementedException();
        }
    }
}

Now, as said, this "works." However, he does not do what I want: he clogs the top-level resource dictionary. I want to remove the resource from the application. and put it under the grid. (Or any panel that I use).

<Grid.Resources>
    <local:SelectionConverter x:Key="SelectionConverter" />
</Grid.Resources>

EDIT: , ( Converter="{StaticResource SelectionConverter}")

" " System.Windows.StaticResourceExtension ", . " 13 " " 38".

:

"SelectionConverter". : .

.xaml:

<Window x:Class="testit.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:local="clr-namespace:testit"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
            <i:Interaction.Triggers>
                <i:EventTrigger EventName="MouseEnter" >
                    <i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
                        <i:InvokeCommandAction.CommandParameter>
                            <Binding Path="Name"
                                     Converter="{StaticResource SelectionConverter}"
                                     RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
                        </i:InvokeCommandAction.CommandParameter>
                    </i:InvokeCommandAction>
                </i:EventTrigger>
            </i:Interaction.Triggers>
        </Rectangle>
        <TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
        <Grid.Resources>
            <local:SelectionConverter x:Key="SelectionConverter" />
        </Grid.Resources>
    </Grid>
</Window>
+4
1

StaticResource , ProvideValue:

, , XAML

Grid.Resources Grid, " ", Grid.

, , , , :

<Grid>
    <Grid.Resources>
        <local:SelectionConverter x:Key="SelectionConverter" />
    </Grid.Resources>

    <Rectangle x:Name="blah" Fill="Yellow" Stroke="Black" Width="100" Height="100">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="MouseEnter" >
                <i:InvokeCommandAction Command="{Binding MouseEnterCommand}">
                    <i:InvokeCommandAction.CommandParameter>
                        <Binding Path="Name"
                                 Converter="{StaticResource SelectionConverter}"
                                 RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=Rectangle}" />
                    </i:InvokeCommandAction.CommandParameter>
                </i:InvokeCommandAction>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Rectangle>
    <TextBlock x:Name="namefield" Text="{Binding Data}" HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>

DynamicResource, , , , , .

+2

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


All Articles