Как обновить динамическое поле с помощью ObservableCollection в сетке данных Silverlight - PullRequest
1 голос
/ 28 июня 2010

Эта проблема может быть плохой дизайн класса или невежество - пожалуйста, потерпите меня:

У меня есть 2 класса - Chip (который реализует INotifyPropertyChanged и представляет один покерный чип) и ChipSet, который реализует INotifyPropertyChanged и имеет ObservableCollection of Chip.

У меня есть Datagrid, который связан с Chip ObservableCollection и Textblock, который связан с ChipSet.

есть. gridChips.ItemsSource = chipset.Chips;

Класс Chip имеет 3 свойства (для простоты) - NumberPerPlayer, ChipValue и TotalValuePerPlayer. TotalValuePerPlayer не имеет набора свойств или связанной закрытой переменной-члена, как другие 2 - он динамически основан на продукте ChipValue и NumberPerPlayer.

Сетка связывает все 3 из этих значений и показывает эти 3 столбца. Редактируются только первые 2, а третий обновляется по мере изменения двух других.

Пока это работает нормально - я обнаружил, что для обновления столбца TotalValuePerPlayer, если обновлен какой-либо из других столбцов, мне пришлось добавить это поле в PropertyChangedEventArgs (см. Код ниже).

Мой первый вопрос - это лучший способ обновления связанных полей классов, основанных на других полях и не изменяющихся в пользовательском интерфейсе (вы не можете редактировать TotalValuePerPlayer напрямую).

public int NumberPerPlayer
{
    get { return numberPerPlayer; }
    set
    {
        if (numberPerPlayer != value)
        {
            numberPerPlayer = value;
            OnPropertyChanged("NumberPerPlayer");
            OnPropertyChanged("TotalValuePerPlayer");
        }
    }
}

public decimal ChipValue
{
    get { return chipValue; }
    set
    {
        if (chipValue != value)
        {
            chipValue = value;
            //all columns that are based on this need to be updated
            OnPropertyChanged("ChipValue");
            OnPropertyChanged("TotalValuePerPlayer");
    }
}

публичный десятичный TotalValuePerPlayer { get {return chipValue * numberPerPlayer; } }

public void OnPropertyChanged(string propertyName)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

Мой второй, главный вопрос заключается в следующем: у меня есть метка, которая показывает сумму всех итогов TotalValuePerPlayer (тупо называется TotalTotalValuePerPlayer). Я поместил это в класс ChipSet следующим образом (он перебирает ObservableCollection и суммирует итоги):

1            public decimal TotalTotalValuePerPlayer
2            {
3                get { 
4          decimal totalTotalValuePerPlayer = 0;
5                 foreach (Chip chip in chips)
6                  {
7                      totalTotalValuePerPlayer += chip.TotalValuePerPlayer;
8                  }
9                  return totalTotalValuePerPlayer;
10     }
11           }

Итак, проблема в том, что когда один из двух столбцов (NumberPerPlayer или ChipValue) это поле основано на изменениях пользовательского интерфейса, оно не обновляется.

Как сообщить родительскому классу - ChipSet, в котором есть элемент TotalTotalValuePerPlayer, который должен обновляться при обновлении одного из его дочерних элементов класса (Chip) в его ObservableCollection?

Если бы TotalTotalValuePerPlayer был в классе Chip, я мог бы просто уведомить его, когда изменились поля, на которых он основывался, но он находится в классе над ним?

Спасибо за любой совет!

Родня

1 Ответ

1 голос
/ 28 июня 2010

Привет, я верю, что вы идете по этому пути правильно, вам просто нужно сделать шаг вперед. Вот как можно ожидать, что классы будут выглядеть:

Chip

public class Chip : INotifyPropertyChanged
{
    private int numberPerPlayer;
    public int NumberPerPlayer
    {
        get { return numberPerPlayer; }
        set
        {
            if (numberPerPlayer != value)
            {
                numberPerPlayer = value;
                OnPropertyChanged("NumberPerPlayer");
                OnPropertyChanged("TotalValuePerPlayer");
            }
        }
    }

    private decimal chipValue;
    public decimal ChipValue
    {
        get { return chipValue; }
        set
        {
            if (chipValue != value)
            {
                chipValue = value;
                //all columns that are based on this need to be updated
                OnPropertyChanged("ChipValue");
                OnPropertyChanged("TotalValuePerPlayer");
            }
        }
    }

    public decimal TotalValuePerPlayer 
    { 
        get
        { 
            return chipValue * numberPerPlayer; 
        } 
    }

    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

ChipSet

public class ChipSet : INotifyPropertyChanged
{
    public ChipSet()
    {
        foreach (var chip in Chips)
        {
            chip.PropertyChanged += (s, e) => { OnPropertyChanged("TotalTotalValuePerPlayer"); };
        }
    }


    public ObservableCollection<Chip> Chips { get; set; }

    public decimal TotalTotalValuePerPlayer
    {
        get
        {
            return Chips.Sum(x => x.TotalValuePerPlayer);
        }
    }

    public void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

Я не проверил это полностью, но оно должно указать вам правильное направление. Надеюсь, это поможет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...