将静态方法/函数绑定到 FuncXAML 中的属性

发布于 2024-10-20 01:28:06 字数 2089 浏览 2 评论 0原文

我正在使用 XAML 创建对象树,其中一个节点如下所示:

public class ExecuteMethod : INode
{
    #region Implementation of INode

    public bool Evaluate()
    {
        return Function != null && Function();
    }

    public string Name { get; set; }

    private string _type;
    public string Type
    {
        get
        {
            if (string.IsNullOrEmpty(_type))
            {
                _type = GetType().Name;
            }

            return _type;
        }
    }


    #endregion

    public Func<bool> Function { get; set; }

}

我的目标是使 XAML 和背后的代码尽可能干净,但现在我创建包装器的情况并非如此每个函数的属性:

public static Func<bool> Func1 { get { return Method1; } }

public static bool Method1()
{
    //Do stuff here
    return true;
}

对于上面的代码,xaml 看起来像这样:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Func1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Func1}"  />
        </Selector>
    </Sequence>
</Root.Child>

我想知道是否有一种快速简便的方法将方法/函数绑定到 Func 属性,我在这里谈论的是方法而不是执行的方法/函数的值。 (我可以考虑在 valueConverter 或 ExecuteMethod 节点/类中使用一些反射魔法,但这感觉又脏又奇怪) 我希望 XAML 的外观示例:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Method1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Method1}"  />
        </Selector>
    </Sequence>
</Root.Child>

感谢您提前提供的任何帮助,并对糟糕的英语语法表示歉意,这不是我的母语:)

I'm working on using XAML to create an object tree and one of the nodes looks like this:

public class ExecuteMethod : INode
{
    #region Implementation of INode

    public bool Evaluate()
    {
        return Function != null && Function();
    }

    public string Name { get; set; }

    private string _type;
    public string Type
    {
        get
        {
            if (string.IsNullOrEmpty(_type))
            {
                _type = GetType().Name;
            }

            return _type;
        }
    }


    #endregion

    public Func<bool> Function { get; set; }

}

My goal is essential to make the XAML and code behind as clean as possible which isn't the case right now where I'm creating wrapper properties for every function:

public static Func<bool> Func1 { get { return Method1; } }

public static bool Method1()
{
    //Do stuff here
    return true;
}

and the xaml looks like this for the above code:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Func1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Func1}"  />
        </Selector>
    </Sequence>
</Root.Child>

I would like to know if there's a quick and easy way to bind methods/functions to the Func property, I'm talking about the method here NOT the value of the executed method/function. (I can think of using some reflection magic in a valueConverter or inside the ExecuteMethod node/class but that just feels dirty and weird)
An example of how I'd like the XAML to look:

<Root 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns="clr-namespace:XamlBT;assembly=XamlBT"  
xmlns:d="clr-namespace:TestBT;assembly=TestBT">
<Root.Child>
    <Sequence Name="sequence1" >
        <ExecuteMethod Name="e1.1" Function="{x:Static d:Program.Method1}" />
        <Selector Name="selector1" >
            <ExecuteMethod Name="e2.1" Function="{x:Static d:Program.Method1}"  />
        </Selector>
    </Sequence>
</Root.Child>

Thanks for any help in advance and sorry for the bad English grammar, it's not my native language :)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

二货你真萌 2024-10-27 01:28:06

谢谢jbtule!

如果有人想要的话,这是解决方案:

[MarkupExtensionReturnType(typeof (Func<bool>))]
public class StaticMethodExtension : MarkupExtension
{
    public StaticMethodExtension(string method)
    {
        Method = method;
    }
     [ConstructorArgument("method")]
    public string Method { get; set; }

    private Func<bool> _func;

    #region Overrides of MarkupExtension

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_func == null)
        {
            int index = Method.IndexOf('.');
            if (index < 0)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }
            string qualifiedTypeName = this.Method.Substring(0, index);
            if (qualifiedTypeName == string.Empty)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }
            IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
            if (service == null)
            {
                throw new ArgumentException("MarkupExtensionNoContext");
            }
            var memberType = service.Resolve(qualifiedTypeName);
            var str = this.Method.Substring(index + 1, (this.Method.Length - index) - 1);

            if (str == string.Empty)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }

            var reflectedFunc = memberType.GetMethod(str,
                                                     BindingFlags.FlattenHierarchy | BindingFlags.Public |
                                                     BindingFlags.Static);

            if (reflectedFunc != null)
            {
                if (reflectedFunc.ReturnType == typeof(bool))
                {
                    var v = Delegate.CreateDelegate(typeof(Func<bool>), reflectedFunc, true);

                    _func = (Func<bool>) v;
                }

            }

        }

        return _func;
    }

    #endregion
}

Thanks jbtule!

here's the solution if anyone wants it:

[MarkupExtensionReturnType(typeof (Func<bool>))]
public class StaticMethodExtension : MarkupExtension
{
    public StaticMethodExtension(string method)
    {
        Method = method;
    }
     [ConstructorArgument("method")]
    public string Method { get; set; }

    private Func<bool> _func;

    #region Overrides of MarkupExtension

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        if (_func == null)
        {
            int index = Method.IndexOf('.');
            if (index < 0)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }
            string qualifiedTypeName = this.Method.Substring(0, index);
            if (qualifiedTypeName == string.Empty)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }
            IXamlTypeResolver service = serviceProvider.GetService(typeof(IXamlTypeResolver)) as IXamlTypeResolver;
            if (service == null)
            {
                throw new ArgumentException("MarkupExtensionNoContext");
            }
            var memberType = service.Resolve(qualifiedTypeName);
            var str = this.Method.Substring(index + 1, (this.Method.Length - index) - 1);

            if (str == string.Empty)
            {
                throw new ArgumentException("MarkupExtensionBadStatic");
            }

            var reflectedFunc = memberType.GetMethod(str,
                                                     BindingFlags.FlattenHierarchy | BindingFlags.Public |
                                                     BindingFlags.Static);

            if (reflectedFunc != null)
            {
                if (reflectedFunc.ReturnType == typeof(bool))
                {
                    var v = Delegate.CreateDelegate(typeof(Func<bool>), reflectedFunc, true);

                    _func = (Func<bool>) v;
                }

            }

        }

        return _func;
    }

    #endregion
}
瞎闹 2024-10-27 01:28:06

我可以想出几种方法来使其看起来更干净,但没有针对您所要求的内容的绑定语法。我猜你最满意的就是 编写你的自己的标记扩展,因此您可以使其看起来像{d:StaticMethod Program.Method1},但您肯定必须使用反射,但缓存很简单并且看起来会更好比值转换器。

I can think of couple ways to make it look cleaner but there isn't a binding syntax for what you are asking. I'm guessing what you would be most happy with would be writing your own markup extension so you could make it look like {d:StaticMethod Program.Method1}, but you would definitely have to use reflection, but it would be trivial to cache and would look better than a value converter.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文