将静态字段绑定为 xaml 中的字典键(获取和设置兼容性!) [英] Bind static field as dictionary key in xaml (get and set compatiblity!)

查看:24
本文介绍了将静态字段绑定为 xaml 中的字典键(获取和设置兼容性!)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将静态嵌套常量作为 dictionary 键绑定到我的 xaml 代码中:

I would like to bind static nested constants into my xaml code as a dictionary key:

<TextBox
   Text="{Binding 
   RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=recipes:ZlsRecipeManagerEdit}, 
   Path=RecipeManagerViewBase.SelectedRecipe.RecipeContent.Data[{x:static ZConstants+Recipes.WT_SUBUNITS_COUNT}], 
   Mode=TwoWay}"/>

{x:static ZConstants+Recipes.WT_SUBUNITS_COUNT}

  • 这是我定义静态属性的地方
public static class ZConstants
{
    public static class Recipes
    {
        public const string WT_SUBUNITS_COUNT = "wt-subunits-count";
    }
}

RecipeManagerViewBase.SelectedRecipe.RecipeContent.Data

  • 是一个Dictionary

应该可以在 dictionary 中编写/编辑条目.

It should be possible to write/edit entries in the dictionary.

同样的问题在这里没有要求也必须设置兼容性:

推荐答案

我通过使用 MarkupExtension

public class DictionaryBindingExtension : MarkupExtension
{
    // ##############################################################################################################################
    // Properties
    // ##############################################################################################################################

    #region Properties

    [ConstructorArgument("path")]
    public PropertyPath Path { get; set; }

    public IValueConverter Converter { get; set; }
    public object ConverterParameter { get; set; }
    public string ElementName { get; set; }
    public RelativeSource RelativeSource { get; set; }
    public object Source { get; set; }
    public bool ValidatesOnDataErrors { get; set; }
    public bool ValidatesOnExceptions { get; set; }
    [TypeConverter(typeof(CultureInfoIetfLanguageTagConverter))]
    public CultureInfo ConverterCulture { get; set; }
    public BindingMode Mode { get; set; } = BindingMode.TwoWay;
    public UpdateSourceTrigger UpdateSourceTrigger { get; set; } = UpdateSourceTrigger.PropertyChanged;

    public string Key { get; set; }

    #endregion

    // ##############################################################################################################################
    // public methods
    // ##############################################################################################################################

    #region public methods

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        IProvideValueTarget target = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
        if (target == null) return this;

        if (string.IsNullOrEmpty(Key))
            return "property 'Key' not defined!";
        PropertyPath path = new PropertyPath($"{Path.Path}[{Key}]");

        Binding binding = new Binding
        {
            Path = path,
            Converter = Converter,
            ConverterCulture = ConverterCulture,
            ConverterParameter = ConverterParameter,
            ValidatesOnDataErrors = ValidatesOnDataErrors,
            ValidatesOnExceptions = ValidatesOnExceptions,
            Mode = Mode,
            UpdateSourceTrigger = UpdateSourceTrigger
        };

        if (ElementName != null)
            binding.ElementName = ElementName;
        if (RelativeSource != null)
            binding.RelativeSource = RelativeSource;
        if (Source != null)
            binding.Source = Source;

        DependencyObject targetObject = target.TargetObject as DependencyObject;
        DependencyProperty targetProperty = target.TargetProperty as DependencyProperty;
        if (targetProperty == null && targetObject == null)
        {
            return EvalBinding(binding);
        }
        else
        {
            BindingOperations.SetBinding(targetObject, targetProperty, binding);

            return targetObject.GetValue(targetProperty);
        }
    }



    public object EvalBinding(Binding b)
    {
        Dummy d = new Dummy();
        BindingOperations.SetBinding(d, Dummy.ValueProperty, b);
        return d.Value;
    }

    #endregion

    // ##############################################################################################################################
    // private class
    // ##############################################################################################################################

    #region private class

    private class Dummy : DependencyObject
    {
        public object Value
        {
            get => (object)GetValue(ValueProperty);
            set => SetValue(ValueProperty, value);
        }

        public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(Dummy), new UIPropertyMetadata(null));

    }

    #endregion
}

<小时>

<TextBox Text="{Ht:DictionaryBinding Path=TestDictionary, Key={x:Static ZConstants+Recipes.WT_SUBUNITS_COUNT}}"/>

这篇关于将静态字段绑定为 xaml 中的字典键(获取和设置兼容性!)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆