Jak bindować wartości z tablicy dwuwymiarowej?

0

Jak w temacie.
Mam projekt zrobiony w MVVM, Caliburn Micro i mam taki problem, ponieważ chcąc odwołać się do Tablicy dwuwymiarowej wyskakuje mi błąd:

1.The type '' was not found. Verify that you are not missing an assembly reference and that all referenced assemblies have been built.

  1. The unnamed argument "0]" must appear before named arguments:

    public class ShellViewModel : Screen
    {
    // Dane
    private BindableCollection<Gracz> _gracze = new BindableCollection<Gracz>();

     // Właściwości danych
     public BindableCollection<Gracz> Gracze
     {
         get { return _gracze; }
         set
         {
             _gracze = value;
             NotifyOfPropertyChange(() => Gracze);
         }
     }
    
    
    
     // Ciało klasy
     public ShellViewModel()
     {
    
         Gracze.Add(new Gracz { IdGracza = 0 });
    
    
         KlasaObslugiUSB.Instancja.Zdarzenie += Po_Zmianie_Stanu_Flagi;
    
         KlasaObslugiUSB.Instancja.Open();
    
    
     }
    
     private void Po_Zmianie_Stanu_Flagi(object sender, EventArgs e)
     {
         Gracze[0].KopiowanieDanychDoTymczasowaTablicaWynikowGracza();
         Gracze[0].KopiowanieWynikowDoTablicaWynikowGracza();
    
     }
    

w xaml:

<label content="{Binding Path=Gracze[0].TablicaWynikowGracza[0,0], Mode=OneWay}" grid.column="0" verticalcontentalignment="Center" horizontalcontentalignment="Center" borderbrush="Black" />
0

To wygląda na odpowiedź

{Binding Path=Gracze[0].TablicaWynikowGracza[0,0], Mode=OneWay}

jest wg mnie niepoprawnie napisany, spróbuj

{Binding Path=Gracze[0].TablicaWynikowGracza[0\,0], Mode=OneWay} // z nawiasem przed przecinkiem
1

Przerobiłem wszystko na Tablice postrzępione. Teraz nie wyskakują błędy, lecz jak odwołać się do danych w XAML? Chodzi o to, że dostęp do danej jest ale jak się zmieni to jej nie odświeża.

0

Jeżeli Ci zależy na bindowaniu pierwszego elementu, to może warto sobie zrobić pomocniczą właściwość:

public Gracz PierwszyGracz { get; set; }

public ShellViewModel()
{
    ...
    PierwszyGracz = Gracze.First();
}

A jeśli chodzi o to odświeżanie to brakuje chyba tego: https://msdn.microsoft.com/pl-pl/library/system.windows.data.binding.notifyonsourceupdated(v=vs.110).aspx

Czyli binding wyglądałby tak:

<label content="{Binding Path=PierwszyGracz.TablicaWynikowGracza[0,0], Mode=OneWay, NotifyOnSourceUpdated=True}" grid.column="0" verticalcontentalignment="Center" horizontalcontentalignment="Center" borderbrush="Black" />

Ogólnie polecam zerknięcie tutaj:
https://stackoverflow.com/questions/26353919/wpf-listview-binding-itemssource-in-xaml
Tutaj właściwość, która jest listą jest bindowana do ListView.ItemsSource.

0

Niestety, nadal coś jest nie tak. Po głębokiej analizie stwierdzam, że przeoczyłem konwersje na stringi. Lecz po dodaniu klasy i zaimplementowaniu jej w View dalej nie chce się odświeżać.

class IntToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int result = (int)value;
        return System.Convert.ToString(result);
    }

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

Binding
<TextBlock x:Name="PierwszyGracz" Text="{Binding Path=TablicaWynikowGracza[0][0], Converter={StaticResource IntToString}, Mode=OneWay, NotifyOnSourceUpdated=True}" FontSize="16"></TextBlock>

Mam wrażenie, że wszystko jest ok. Ale czemu nie odświeża jak przyjdą dane to nie mam zielonego pojęcia.

0

Możesz pokazać jak wygląda klasa Gracz?

Ona też musi implementować **INotifyPropertyChanged ** i w set'erach musisz wywoływać metodę OnPropertyChanged.

0

[AddINotifyPropertyChangedInterface]
public class Gracz : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;

    private int[][] _tablicaWynikowGracza;

  
   
          public int[][] TablicaWynikowGracza
    {
        get => _tablicaWynikowGracza; set
        {
            if (value != _tablicaWynikowGracza)
            {
                _tablicaWynikowGracza = value;
                OnPropertyChanged("TablicaWynikowGracza");
                
            }
        }
    }


    // Ciało klasy
    public Gracz()
    {
        
        TablicaWynikowGracza = new int[10][];
        TablicaWynikowGracza[0] = new int[3];
        TablicaWynikowGracza[1] = new int[3];
        TablicaWynikowGracza[2] = new int[3];
        TablicaWynikowGracza[3] = new int[3];
        TablicaWynikowGracza[4] = new int[3];
        TablicaWynikowGracza[5] = new int[3];
        TablicaWynikowGracza[6] = new int[3];
        TablicaWynikowGracza[7] = new int[3];
        TablicaWynikowGracza[8] = new int[3];
        TablicaWynikowGracza[9] = new int[3];
  
        
    }

           public virtual void OnPropertyChanged(string propertyName)
    {
        var propertyChanged = PropertyChanged;
        if (propertyChanged != null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}
1

Spróbuj może tą tablicę dwuwymiarową przerobić. Lepiej jest korzystać z jakiejś listy obiektów. Jeśli to mają być trzy wyniki, to jakaś prosta klaska, która zawiera trzy właściwości.
Oczywiście ta klasa też powinna implementować INotifyPropertyChanged.
Ogólnie jak korzystasz z takiej tablicy dwuwymiarowej, to nie za bardzo jest jak odświeżyć jej binding.

Programowanie, to modelowanie rzeczywistości ;) więc zamodeluj sobie tą rzeczywistość...

1 użytkowników online, w tym zalogowanych: 0, gości: 1