如何在Xaml中使用委托类型属性?

时间:2011-06-09 05:56:35

标签: c# wpf

我有一个委托类型:

public delegate bool CheckFormatDelegate(int row, int col, ref string text);

这已在Xaml对象的Property中使用:

public virtual CheckFormatDelegate CheckFormat { get; set; }

我将属性值设置为一组委托中的一个,例如:

public class FCS
{
    public static bool FormatDigitsOnly(int row, int col, ref string text)
    {
        ...
    }
}

如果我在codebehind中设置属性,一切都很好。但是,如果我在Xaml中设置它:

<mui:DXCell CheckFormat="mui:FCS.FormatDigitsOnly"/>

当我运行我的应用程序时,我得到一个例外:“'CheckFormatDelegate'类型没有公共TypeConverter类。”有谁知道是否有一组内置的转换器/标记扩展,如用于RoutedEvent的转换器/标记扩展?或者还有其他方法吗?

2 个答案:

答案 0 :(得分:3)

您获得的错误是因为它试图将字符串转换为对XAML编译器有意义的字符串。您可以为它创建一个类型转换器(使用反射实现),但有更简单的方法可以解决这个问题。

使用x:Static标记扩展名。

<object property="{x:Static prefix:typeName.staticMemberName}" ... />

请参阅MSDN文档:

http://msdn.microsoft.com/en-us/library/ms742135.aspx

根据该页面:

  

...大多数有用的静态属性都有支持,例如类型转换器,便于使用而不需要{x:静态} ......

我猜你的自定义代理没有,并要求你使用x:Static

修改

我试过了,正如你所提到的那样,它似乎不适用于方法。但它确实可以对抗属性。这是一个解决方法:

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525">
    <local:Class1 CheckFormat="{x:Static local:FCS.FormatDigitsOnly}" />
</Window>

namespace WpfApplication1
{
    public delegate bool CheckFormatDelegate(int row, int col, ref string text);

    public class Class1
    {
        public virtual CheckFormatDelegate CheckFormat { get; set; }
    }

    public class FCS
    {
        private static bool FormatDigitsOnlyImpl(int row, int col, ref string text)
        {
            return true;
        }

        public static CheckFormatDelegate FormatDigitsOnly
        {
            get { return FormatDigitsOnlyImpl; }
        }
    }
}

修改2

我不想窃取他们的答案(所以请相反地投票给他们,除非你更喜欢房产的解决方案),但这里有一个问题,为你提供更好的解决方案:

Binding of static method/function to Func<T> property in XAML

答案 1 :(得分:1)

最简单的选择是使用接口而不是委托

public interface IFormatChecker
{
    bool CheckFormat(int row, int col, ref string text);
}

public sealed class CheckFormatByDelegate : IFormatChecker
{
    ...
}

public class FCS
{
    public static readonly IFormatChecker FormatDigitsOnly = new CheckFormatByDelegate();
}

<mui:DXCell CheckFormat="{x:Static mui:FCS.FormatDigitsOnly}"/>

如果您不喜欢界面

,我想您可以创建自己的自定义MarkupExtension