2013-04-20 15 views
9

Çok boyutlu bir dizideki belirli bir öğeye bağlantı oluşturmak için XAML dizesini formüle etme konusunda sorun yaşıyorum.WPF xaml'daki çokboyutlu diziye bağlanma

DataContext aşağıdaki komutları içerir:

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

XAML aşağıdaki komutları içerir:

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

bağlanma çalışmaları OneDimension ve Jagged beklendiği gibi. TwoDimension'a bağlanma çalışmıyor ve yanlış görünüyor, ancak XAML ayırıcıyı , kullanmama izin vermiyor, bu yüzden iki boyutlu bir diziye nasıl bağlanacağımı bilmiyorum.

Bu: XAML Bağlama Oluşturucu için iki argüman sahip olarak yorumlanır olur çünkü

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

derleme değil. Ayrıştırıcıdan kurtulmanın bir yolu var mı, yoksa bunu bilmediğim başka bir yol var mı?


DÜZENLEME:

Sadece bu

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

gibi ayırıcı kaçmak mümkün olduğunu öğrendim ya da sadece bu

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

gibi belirteçler ile argüman çevreleyen Ancak bu satır şu anda bir istisna getiriyor: System.ArgumentException {"Das Array war kein eindimension ales Array. "} unfortunatelly C# kendi ana dilimde yüklü - bok gibi can sıkıcı ... bu yüzden kabaca" {Array onedimensionale Array "anlamına gelmiyordu.}}

Aslında çok boyutlu dizileri bağlamak imkansız mı?

+0

Bildiğim kadarıyla saf 'Xaml' çok boyutlu diziler bağlamak mümkün değildir farkındayım olarak, işi yapmak için bir' IValueConverter' oluşturmak zorunda kalacaktır. –

+0

Hmmm, bunu yapmak için şunu bilmeliyim ki ... bu Dizi olurdu ... ama dizi için bir ValueConverter var - bundan eminim. Onw'imi enjekte edebilir miyim? – Johannes

+0

Bu bağlantıyı deneyin. Umarım https://nicoschertler.wordpress.com/2014/05/22/binding-to-a-2d-array-in-wpf/ –

cevap

8

Böyle tanımlanan bir MultivalueConverter kullanarak iki boyutlu bir dizi bağlayabilirsiniz:

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

MultiDimensionalCoverter 3 parametre, İki Dimention diziyi artı iki endeksler, almak ve Xaml böyle olacağını:

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

Endeksleri, VM'nizdeki özellikler olarak tanımlamak muhtemelen daha uygundur, sadece göstermek için sabit değer kullanıyorum.

1

Varsayılan olarak WPF XAML, bunun gibi bir 2D diziye bağlanmaya izin vermez. Sadece 1D diziler. Ancak, hiçbir şey imkansız değildir. Sadece zaman alıcı. Bunu yapmak için bir özel sınıf oluşturmanız ve bunu bir bağlantı yolu olarak kullanmanız gerekir.

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

Sonra XAML bağlayabilir: solüsyonun

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

Source.

Bu, başlamam için çok boyutlu bir diziyi kullanarak soru sormamı sağlayan performansı etkileyebilir mi? Daha kolay bir uygulama olabilecek listeleri kullanabilirsiniz. this solution'a bir göz atın.