[英]C# WPF Datagrid doesn't dynamically sort on data update
我的datagrid遇到了一些麻煩:
當我更新一些數據(來自模型)時,它會顯示在我的DataGrid上,但是如果單擊標題以對列進行排序,那么當我更新現有數據時,它就會開始橫擺。
這里有
2
1例
S:
我已經看到了多個答案,但有人說DataGridTextColumn應該不成問題...
所以我想知道是否是由於字典的緣故...
我知道新數據的第一個問題與字典有關。
賓語。
public class Player : INotifyPropertyChanged
{
private string _id;
private string _name;
private int _damage;
private int _heal;
private int _dps;
private int _hps;
private int _time = 1;
public Player(string id, string name)
{
_name = name;
_id = id;
}
public event PropertyChangedEventHandler PropertyChanged;
public string Id
{
get { return _id; }
private set
{
_id = value;
}
}
public string Name
{
get { return _name; }
private set
{
_name = value;
NotifyPropertyChanged("Name");
}
}
public int Damage
{
get { return _damage; }
set
{
_damage = value;
NotifyPropertyChanged("Damage");
Dps = _damage / _time;
}
}
public int Heal
{
get { return _heal; }
set
{
_heal = value;
NotifyPropertyChanged("Heal");
Hps = _heal / _time;
}
}
public int Dps
{
get { return _dps; }
private set
{
_dps = value;
NotifyPropertyChanged("Dps");
}
}
public int Hps
{
get {return _hps; }
private set
{
_hps = value;
NotifyPropertyChanged("Hps");
}
}
public int Time
{
get { return _time; }
set
{
_time = value;
Dps = _damage / _time;
Hps = _heal / _time;
}
}
private void NotifyPropertyChanged(string name)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
的ObservableCollection
public sealed class ShortList
{
private static readonly ShortList instance = new ShortList();
private ObservableCollection<Player> playerList = new ObservableCollection<Player>();
private ShortList()
{
}
public static ShortList getShortList
{
get
{
return instance;
}
}
public ObservableCollection<Player> getPlayerList
{
get
{
return playerList;
}
}
public void updatePlayer(string id, string name, int damage, int heal, int time)
{
Player player;
player = findPlayer(id);
if (player != null)
{
player.Damage = player.Damage + damage;
player.Heal = player.Heal + heal;
player.Time = player.Time + time;
}
else
{
player = new Player(id, name);
player.Damage = damage;
player.Heal = heal;
player.Time = time;
playerList.Add(player);
}
}
public void clear()
{
playerList.Clear();
}
private Player findPlayer(string id)
{
foreach (Player p in playerList)
{
if (p.Id == id)
{
return p;
}
}
return null;
}
}
XAML
<DataGrid AutoGenerateColumns="False"Name="playerDataGrid" IsReadOnly="True" ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTextColumn Header="Nom" Binding="{Binding Name}" MinWidth="35"/>
<DataGridTextColumn Header="Degats" Binding="{Binding Damage}" MinWidth="45" />
<DataGridTextColumn Header="DPS" Binding="{Binding Dps}" MinWidth="29" />
<DataGridTextColumn Header="Soins" Binding="{Binding Heal}" MinWidth="35" />
<DataGridTextColumn Header="HPS" Binding="{Binding Hps}" MinWidth="29" />
</DataGrid.Columns>
</DataGrid>
窗口后面的代碼
public partial class MiniParser : Window
{
public MiniParser()
{
InitializeComponent();
playerDataGrid.ItemsSource = ShortList.getShortList.getPlayerList;
temporyFill();
}
private void temporyFill()
{
ShortList.getShortList.updatePlayer("1234", "ABCD", 100, 0, 2);
ShortList.getShortList.updatePlayer("1234", "ABCD", 100, 0, 0);
ShortList.getShortList.updatePlayer("123", "ABC", 50, 0, 1);
ShortList.getShortList.updatePlayer("234", "ABC", 0, 50, 1);
ShortList.getShortList.updatePlayer("345", "BCD", 1000, 25, 25);
ShortList.getShortList.updatePlayer("456", "CDE", 250, 0, 25);
}
private void startMI_Click(object sender, RoutedEventArgs e)
{
ShortList.getShortList.updatePlayer("5678", "BABA", 100, 100, 100);
ShortList.getShortList.updatePlayer("1234", "ABCD", 100, 0, 0);
}
}
當然,后面的大多數代碼都用於測試目的...但是想法是模型正在更新,視圖需要反映更改(即使是排序)。
當屬性更新時,您不會引發PropertyChanged
事件。 這意味着name
從""
更改為"Test"
的新項目,或已更改的現有項目,都不會引發PropertyChanged事件以使UI知道值已更改並且需要更新。
要解決此問題,請使屬性在更改時引發PropertyChanged事件。
public class Player : INotifyPropertyChanged
{
private string _name;
public string Name
{
get { return _name; }
set
{
if (_name != value)
{
_name = value;
RaisePropertyChanged("Name");
}
}
}
另外,我正在重新閱讀您的問題,我不知道您對ObservableDictionary
所做的事情,但是我建議您進行更改,以便您的DataGrid直接綁定到ObservableCollection<Player>
。 我懷疑這是您問題的一部分。
var playerCollection = new ObservableCollection<Player>();
playerCollection.Add(new Player { Name = "Test 1" });
playerCollection.Add(new Player { Name = "Test 2" });
playerCollection.Add(new Player { Name = "Test 3" });
playerDataGrid.ItemsSource = playerCollection;
我找到了一個解決方案,到目前為止一切順利:
問題是,當您更改ObservableCollection中已經存在的對象中字段的值時,ObservableCollection不會觸發事件“ CollectionChanged”。 (可能是因為您沒有更改對它的引用)。
這是一個例子:
ObservableCollection<MyObject> myCollection = new ObservableCollection<MyObject>();
myCollection.add("CollectionChanged","Yes");
//Let's say I had a method to find a object with the first string and to change the second string
myCollection.change("CollectionChanged", "No");
可以猜到,第二部分是當我更改現有對象的字段CollectionChanged時未觸發...
因此,我實現的解決方案如下:
class ObsCollection<T> : ObservableCollection<T>
{
public void UpdateCollection()
{
OnCollectionChanged(new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Reset));
}
}
您要做的就是創建新的集合類型,然后在更改現有對象的字段值時,調用UpdateCollection()方法。
此解決方案來自吳學松。
我想說Rachel也是很大的幫助。
移動任何看起來像這樣的代碼:
this.NotifyPropertyChanged("somepropertyname");
進入屬性的setter方法。 這就是二傳手的目的。
另外,我還建議您使用ObservableCollection<T>
代替ObservableDictionary<TKey,TValue>
。 對於WPF綁定,它們非常常見。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.