Riju
Riju

Reputation: 576

Custom DependencyProperty with custom datatype

I want to create a custom DependencyProperty for a usercontrol

 public Table Grids
    {
        get { return (Table)GetValue(GridsProperty); }
        set { SetValue(GridsProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Grids.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty GridsProperty =
                DependencyProperty.Register("Grids", typeof(Table), 
                typeof(MyViewer), new UIPropertyMetadata(10));

Here Table is a custom datatype used to store rows & Columns. That will help me in using them like;

<my:MyViewer 
    HorizontalAlignment="Left" 
    Margin="66,54,0,0" 
    x:Name="MyViewer1" 
    VerticalAlignment="Top" 
    Height="400" 
    Width="400"
    Grids="10"/>

or

<my:MyViewer 
    HorizontalAlignment="Left" 
    Margin="66,54,0,0" 
    x:Name="MyViewer1" 
    VerticalAlignment="Top" 
    Height="400" 
    Width="400"
    Grids="10,20"/>

I tried to define the Table datatype as;

public class Table 
    {
        public int Rows { get; set; }
        public int Columns { get; set; }

        public Table(int uniform)
        {
            Rows = uniform;
            Columns = uniform;
        }

        public Table(int rows, int columns)
        {
            Rows = rows;
            Columns = columns;
        }
    }

but it's not working; when i use Grids="10" in XAML it breaks. Can anybody help me to achive this?

Upvotes: 0

Views: 216

Answers (2)

Clemens
Clemens

Reputation: 128061

The default value in the property metadata is of the wrong type. This will result in an exception when the MyViewer class is loaded. Set the default value to e.g. new Table(10).

Besides that, XAML/WPF will not automatically convert the strings "10" or "10,20" to instances of your Table class by calling the right constructors. You will have to write a TypeConverter to perform this conversion.

A simple TypeConverter could look like this:

public class TableConverter : TypeConverter
{
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
        return sourceType == typeof(string);
    }

    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
        string tableString = value as string;
        if (tableString == null)
        {
            throw new ArgumentNullException();
        }

        string[] numbers = tableString.Split(new char[] { ',' }, 2);
        int rows = int.Parse(numbers[0]);
        int columns = rows;

        if (numbers.Length > 1)
        {
            columns = int.Parse(numbers[1]);
        }

        return new Table { Rows = rows, Columns = columns };
    }
}

The TypeConverter would be associated with your Table class like this:

[TypeConverter(typeof(TableConverter))]
public class Table
{
    ...
}

Upvotes: 2

XamlZealot
XamlZealot

Reputation: 722

Isn't the default value you are setting in the registration method a data type mismatch? I believe you want the first FrameworkPropertyMetadata parameter to be something like:

new FrameworkPropertyMetadata(new Table())

or

new FrameworkPropertyMetadata(null)

Then in XAML you could do the following:

<my:MyViewer>
    <my:MyViewer.Grids>
        <Table Rows="10" Column="20"/>
    </my:MyViewer.Grids>
</my:MyViewer> 

Upvotes: 3

Related Questions