wpf WPF绑定到xaml中的多维数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/16119200/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:38:09  来源:igfitidea点击:

WPF Binding to multidimensional array in the xaml

wpfdata-bindingbinding

提问by Johannes

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

我无法制定 XAML 字符串以链接到多维数组中的特定元素。

The DataContext contains the following lines:

DataContext 包含以下几行:

    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:

XAML 包含以下几行:

    <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 OneDimensionand Jaggedwork as expected. The binding to TwoDimensiondoes 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.

结合到OneDimensionJagged正常工作。绑定到TwoDimension不起作用并且似乎是错误的,但是 XAML 不允许我使用分隔符,,所以我不知道如何绑定到二维数组。

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?

无法编译,因为 XAML 被解释为具有绑定构造函数的两个参数。有什么方法可以逃避解析器,还是有另一种我不知道的写法?



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

然而,这一行现在导致了一个例外:System.ArgumentException{"Das Array war kein einDimensiones Array."} 不幸的是,C# 用我的母语安装了自己 - 烦人的狗屎......所以这粗略地翻译成 {"The Array was not an onedimensionale Array. "}

Is it actually impossible to bind multidimensional arrays?

绑定多维数组实际上是不可能的吗?

采纳答案by ELH

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

您可以使用如下定义的 MultivalueConverter 绑定到二维数组:

 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 :

MultiDimensionalCoverter 得到 3 个参数,二维数组加上两个索引,Xaml 将是这样的:

<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.

将索引定义为 VM 中的属性可能更合适,我使用固定值只是为了演示。

回答by AzzamAziz

By default WPF XAML does not allow binding to a 2D array like this. Only 1D arrays. However, nothing is impossible. Just time consuming. You will have to create a custom class in order to do this and use that as a way of binding.

默认情况下,WPF XAML 不允许绑定到这样的二维数组。只有一维数组。然而,没有什么是不可能的。就是费时间。您必须创建一个自定义类才能执行此操作并将其用作绑定方式。

/// <summary>
/// This class is a bindable encapsulation of a 2D array.
/// </summary>
/// <typeparam name="T"></typeparam>
public class BindableTwoDArray<T> : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    private void Notify(string property)
    {
        var pc = PropertyChanged;
        if (pc != null)
            pc(this, new PropertyChangedEventArgs(property));
    }

    T[,] data;

    public T this[int c1, int c2]
    {
        get { return data[c1, c2]; }
        set
        {
            data[c1, c2] = value;
            Notify(Binding.IndexerName);
        }
    }

    public string GetStringIndex(int c1, int c2)
    {
        return c1.ToString() + "-" + c2.ToString();
    }

    private void SplitIndex(string index, out int c1, out int c2)
    {
        var parts = index.Split('-');
        if (parts.Length != 2)
            throw new ArgumentException("The provided index is not valid");

        c1 = int.Parse(parts[0]);
        c2 = int.Parse(parts[1]);
    }

    public T this[string index]
    {
        get
        {
            int c1, c2;
            SplitIndex(index, out c1, out c2);
            return data[c1, c2]; 
        }
        set
        {
            int c1, c2;
            SplitIndex(index, out c1, out c2);
            data[c1, c2] = value;
            Notify(Binding.IndexerName);
        }
    }

    public BindableTwoDArray(int size1, int size2)
    {
        data = new T[size1, size2];
    }

    public static implicit operator T[,](BindableTwoDArray<T> a)
    {
        return a.data;
    }
}

Then you can bind to XAML:

然后你可以绑定到 XAML:

<TextBlock Text="{Binding MyBindableTwoDArray[2-5]}"/>

Sourceof solution.

解决方案的来源

This may affect performance which leads me to question using a multidimensional array to begin with? You may use lists which may be an easier implementation. Take a look at this solution.

这可能会影响性能,这让我开始质疑使用多维数组?您可以使用列表,这可能更容易实现。看看这个解决方案