2013-04-20 7 views
9

Ho difficoltà a formulare la stringa XAML per collegarla a un elemento specifico in una matrice multidimensionale.WPF Associazione all'array multidimensionale nell'xaml

Il DataContext contiene le seguenti righe:

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

Il XAML contiene le seguenti righe:

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

Il legame OneDimension e Jagged funzionano come previsto. Il collegamento a TwoDimension non funziona e sembra essere sbagliato, tuttavia XAML non mi consente di utilizzare il separatore ,, quindi non so come associare a un array bidimensionale.

Questo:

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

non compila perché il XAML viene interpretato come avente due argomenti per il Binding Costruttore. C'è un modo per sfuggire al parser o esiste un altro modo di scrivere ciò di cui non sono a conoscenza?


EDIT:

ho scoperto che è possibile evitare il separatore simili

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

o semplicemente circondano la discussione con marcatori come questa

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

Tuttavia questa riga ora porta ad un'eccezione: System.ArgumentException {"Das Array war kein eindimension ales Array. "} sfortunatamente C# si è installato nella mia lingua nativa - fastidioso come merda ... quindi questo si traduce approssimativamente in {" La matrice non era una matrice onedimensionale. "}

È davvero impossibile associare gli array multidimensionali?

+0

Per quanto ne so, non è possibile associare matrici multidimensionali in puro 'Xaml', sarà necessario creare un' IValueConverter' per eseguire il lavoro. –

+0

Hmmm, per farlo dovrei sapere il tipo ... che sarebbe Array ... ma c'è un ValueConverter per array - ne sono sicuro. Posso iniettare il mio onw? – Johannes

+0

Prova questo link. Spero che aiuti https://nicoschertler.wordpress.com/2014/05/22/binding-to-a-2d-array-in-wpf/ –

risposta

8

È possibile associare a una matrice bidimensionale utilizzando un MultivalueConverter definita in questo modo:

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

che MultiDimensionalCoverter ottenere 3 parametri, l'array Due Dimention più i due indici, e il codice XAML sarà così:

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

definire gli indici come proprietà nella VM è probabilmente più appropriato, sto usando il valore fisso solo per dimostrare.

1

Per impostazione predefinita, XAML WPF non consente il collegamento a un array 2D come questo. Solo array 1D. Tuttavia, nulla è impossibile. Solo in termini di tempo. Dovrai creare una classe personalizzata per farlo e usarla come metodo di associazione.

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

Poi si può associare a XAML:

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

Source di soluzione.

Ciò potrebbe influire sulle prestazioni che mi portano a porre domande usando un array multidimensionale per cominciare? È possibile utilizzare elenchi che potrebbero essere un'implementazione più semplice. Dai uno sguardo allo this solution.