Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF Binding to multidimensional array in the xaml

I have trouble to formulate the XAML string to link to a specific element in a multidimensional array.

The DataContext contains the following lines:

    private String[] _OneDimension = { "[0]", "[1]" };
    private String[][] _Jagged = { new String[] { "[0,0]", "[0,1]" }, new String[] { "[1,0]", "[1,1]" } };
    private String[,] _TwoDimension = { { "[0,0]", "[0,1]" }, { "[1,0]", "[1,1]" } };

    public String[] OneDimension { get { return _OneDimension; } }
    public String[][] Jagged { get { return _Jagged; } }
    public String[,] TwoDimension { get { return _TwoDimension; } }

The XAML contains the following lines:

    <StackPanel>
        <Button Content="{Binding OneDimension[1]}" Width="100" Height="50" />
        <Button Content="{Binding Jagged[1][1]}" Width="100" Height="50" />
        <Button Content="{Binding TwoDimension[1][1]}" Width="100" Height="50" />
    </StackPanel>

The binding to OneDimension and Jagged work as expected. The binding to TwoDimension does not work and appears to be wrong, however the XAML does not allow me to use the separator , so I do not know how to bind to a two dimensional array.

This:

        <Button Content="{Binding TwoDimension[1,1]}" Width="100" Height="50" />

does not compile because the XAML gets interpreted as having two arguments for the Binding Constructor. Is there some way to escape the parser or is there another way of writing this that I am not aware of?


EDIT:

I just found out that it is possible to escape the separator like this

<Button Content="{Binding TwoDimension[1\,1]}" Width="100" Height="50" />

or just surround the argument with markers like this

<Button Content="{Binding 'TwoDimension[1,1]'}" Width="100" Height="50" />

However this line now leads to an exception: System.ArgumentException {"Das Array war kein eindimensionales Array."} unfortunatelly C# installed itself in my native language - annoying as shit... so this roughly translates to {"The Array was not a onedimensionale Array."}

Is it actually impossible to bind multidimensional arrays?

like image 740
Johannes Avatar asked Apr 20 '13 10:04

Johannes


People also ask

How do I bind with XAML?

One-Way Data Binding The following XAML code creates four text blocks with some properties. Text properties of two text blocks are set to “Name” and “Title” statically, while the other two text blocks Text properties are bound to “Name” and “Title” which are class variables of Employee class which is shown below.

What is two way binding WPF?

In two way we can change data in sources control and target control. Target to source and source to target means if we change source control value then it will automatically change target control value. And vice-a versa for source control. That's why it's called two-way data binding.

How many types of binding are there in WPF?

WPF binding offers four types of Binding. Remember, Binding runs on UI thread unless otherwise you specify it to run otherwise. OneWay: The target property will listen to the source property being changed and will update itself.

How binding happens in WPF?

Data binding is a mechanism in WPF applications that provides a simple and easy way for Windows Runtime apps to display and interact with data. In this mechanism, the management of data is entirely separated from the way data. Data binding allows the flow of data between UI elements and data object on user interface.


1 Answers

You can bind to a Two dimensional array using a MultivalueConverter defined like this :

 class MultiDimensionalCoverter:IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        return (values[0] as String[,])[(int) values[1], (int) values[2]];  
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

that MultiDimensionalCoverter get 3 parameters, the Two Dimention array plus the two indexes, and the Xaml will be like this :

<Window.Resources>
        <wpfApp:MultiDimensionalCoverter x:Key="MultiDimensionalCoverter"/>
    </Window.Resources>
    <Grid>
        <StackPanel>
            <Button Content="{Binding OneDimension[1]}" Width="100" Height="50" />
            <Button Content="{Binding Jagged[1][1]}" Width="100" Height="50" />
            <Button Width="100" Height="50" >
                <Button.Resources>
                    <system:Int32 x:Key="1">1</system:Int32>
                </Button.Resources>
                <Button.Content>
                    <MultiBinding Converter="{StaticResource MultiDimensionalCoverter}">
                        <Binding Path="TwoDimension"/>
                        <Binding Source="{StaticResource 1}"/>
                        <Binding Source="{StaticResource 1}"/>
                    </MultiBinding>
                </Button.Content>
            </Button>
        </StackPanel>
    </Grid>

defining the indexes as properties in your VM is probably more appropriate, i am using fixed value only to demonstrate.

like image 138
SamTh3D3v Avatar answered Sep 22 '22 04:09

SamTh3D3v