2

I have a delegate type:

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

This has been used in a Property on a Xaml object:

public virtual CheckFormatDelegate CheckFormat { get; set; }

I set the property value to one of a group of delegates, for example:

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

If I set the property in codebehind, all is well. However, if I set it in Xaml:

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

when I run my app I get an exception: "'CheckFormatDelegate' type does not have a public TypeConverter class.". Does anyone know if there's a built in set of converters/markup extensions like the ones used for RoutedEvent? Or is there some other way around this?

Ed Bayiates
  • 11,060
  • 4
  • 43
  • 62
  • possible duplicate of [Binding of static methode/function to Func property in XAML](http://stackoverflow.com/questions/5146946/binding-of-static-methode-function-to-funct-property-in-xaml) – Merlyn Morgan-Graham Jun 09 '11 at 07:17
  • Looks like that solution will in fact work for me. If you can put this in your answer I will accept it. Thanks! – Ed Bayiates Jun 09 '11 at 07:37

2 Answers2

3

The error you are getting is because it is trying to convert a string into something meaningful to the XAML compiler. You might be able to create a type converter for it (implemented with reflections), but there are simpler ways to work around this.

Use the x:Static markup extension.

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

See the MSDN docs:

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

According to that page:

... most of the useful static properties have support such as type converters that facilitate the usage without requiring {x:Static} ...

I'm guessing your custom delegate does not, and would require you to use x:Static.

Edit

I tried it out, and it doesn't seem to work on methods, as you mentioned. But it does work against properties. Here is a work-around:

<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; }
        }
    }
}

Edit 2

I don't want to steal their answers (so please up-vote them instead, unless you prefer the property work-around), but here is a question that has an even better solution for you:

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

Community
  • 1
  • 1
Merlyn Morgan-Graham
  • 58,163
  • 16
  • 128
  • 183
  • The first thing I had tried was x:Static. I assume you mean something like this: This does not compile. The compiler complains that it cannot find FormatFilterDigits. The documentation states that you can only use x:Static on certain items and I do not believe methods are allowed. – Ed Bayiates Jun 09 '11 at 06:29
1

Simplest option is to use an interface rather than a delegate

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}"/>

I suppose you could create your own custom MarkupExtension if you didn't like the interface

cordialgerm
  • 8,403
  • 5
  • 31
  • 47
  • I'm not sure how this helps. You can't assign classes in Xaml either, that I know of. I'd really like to stick with delegates anyway, since this kind of method would force me to declare dozens of classes for all the format checkers. – Ed Bayiates Jun 09 '11 at 06:40