数据绑定列表框未更新为可观察集合 WPF 中的正确值
Databound list box not updating to correct values from observable collection WPF
我是 WPF 的新手,所以可能是我错过的非常简单的东西。
我有一个列表框,其中包含来自 static observableCollection<myClass>
的数据绑定 Class 属性。该集合每秒从网络流源更新几次,从调试中我可以看出,该集合正在正确更新。声明如下: static ObservableCollection<PumpItem> pumpCollection = new ObservableCollection<PumpItem>();
其中 PumpItem
是我的 class.
的名称
这并不是说列表框没有显示任何内容,它正在更新以显示添加到集合中的任何新值,但这些值只会反映它们进入集合的第一时刻的属性。
列表框的值是这样绑定的:
<ListBox x:Name="pumpListBox" ItemsSource="{Binding PumpCollection}" Grid.IsSharedSizeScope="True" Margin="0,0,153,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ID" />
<ColumnDefinition SharedSizeGroup="State" />
<ColumnDefinition SharedSizeGroup="Selection" />
<ColumnDefinition SharedSizeGroup="Fuel Pumped" />
<ColumnDefinition SharedSizeGroup="Cost" />
</Grid.ColumnDefinitions>
<TextBlock Margin="2" Text="{Binding PumpID}" Grid.Column="0"/>
<TextBlock Margin="2" Text="{Binding State}" Grid.Column="1"/>
<TextBlock Margin="2" Text="{Binding Selection}" Grid.Column="2"/>
<TextBlock Margin="2" Text="{Binding FuelPumped}" Grid.Column="3"/>
<TextBlock Margin="2" Text="{Binding FuelCost}" Grid.Column="4"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我在后面的代码中有这个声明,以便为集合设置资源:
public static ObservableCollection<PumpItem> PumpCollection
{
get { return pumpCollection; }
}
在我的 `MainWindow() 构造函数中,我设置了:
this.DataContext = this;
在 InitialiseComponent(); and my background worker thread to receive network inputs to update the list:
worker.RunWorkerAsync() 之前;`
此后台线程然后循环不断更新流中的集合并调用资源更新:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
//background tasks
Thread.Sleep(500); //allows the ui time to update and initialise
string s_decryptedMessage = string.Empty;
App.Current.Dispatcher.Invoke((Action)(() =>
{
Resources["PumpCollection"] = pumpCollection;
}));
while (true)
{
byteMessage = Recieve(stream);//get the number of pumps about to be recieved
Interact(byteMessage); //signal server to update pumplist
}
}
如果有帮助,我的 class 代码是:
namespace PoSClientWPF
{
public 枚举 pumpState
{
可用的,
等待,
抽水,
支付中
};
public enum fuelSelection
{
Petrol,
Diesel,
LPG,
Hydrogen,
None
};
public class PumpItem
{
private string pumpID;
public string PumpID
{
get
{
return pumpID;
}
set
{
pumpID = value;
}
}
private double fuelPumped;
public double FuelPumped
{
get
{
return fuelPumped;
}
set
{
fuelPumped = value;
}
}
private double fuelCost;
public double FuelCost
{
get
{
return fuelCost;
}
set
{
fuelCost = Math.Round(value, 2); //cost to two DP
}
}
private fuelSelection selection;
public fuelSelection Selection
{
get
{
return selection;
}
set
{
selection = value;
}
}
private pumpState state;
public pumpState State
{
get
{
return state;
}
set
{
state = value;
}
}
public PumpItem(string _ID, pumpState _state, fuelSelection _selection)
{
this.pumpID = _ID;
this.FuelPumped = 0;
this.FuelCost = 0;
this.Selection = _selection;
this.State = _state;
}
}
}
正如我所说,我是 WPF 的新手,因此非常感谢任何指导或解决方案。谢谢。
Ash 完全正确,但这里有一个快速示例供您略读。这是一个 ViewModelBase 的示例,通常所有 ViewModel 都继承自该示例。来自我的一个回购协议。这就是您调用 OnChangedEvent 的方式。
private sample _Item;
public sample Item
{
get
{
return _Item;
}
set
{
if (_Item != value)
{
_Item = value;
OnPropertyChanged("Item");
}
}
}
这将在属性更改时更新所有内容。
我是 WPF 的新手,所以可能是我错过的非常简单的东西。
我有一个列表框,其中包含来自 static observableCollection<myClass>
的数据绑定 Class 属性。该集合每秒从网络流源更新几次,从调试中我可以看出,该集合正在正确更新。声明如下: static ObservableCollection<PumpItem> pumpCollection = new ObservableCollection<PumpItem>();
其中 PumpItem
是我的 class.
这并不是说列表框没有显示任何内容,它正在更新以显示添加到集合中的任何新值,但这些值只会反映它们进入集合的第一时刻的属性。
列表框的值是这样绑定的:
<ListBox x:Name="pumpListBox" ItemsSource="{Binding PumpCollection}" Grid.IsSharedSizeScope="True" Margin="0,0,153,0">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="ID" />
<ColumnDefinition SharedSizeGroup="State" />
<ColumnDefinition SharedSizeGroup="Selection" />
<ColumnDefinition SharedSizeGroup="Fuel Pumped" />
<ColumnDefinition SharedSizeGroup="Cost" />
</Grid.ColumnDefinitions>
<TextBlock Margin="2" Text="{Binding PumpID}" Grid.Column="0"/>
<TextBlock Margin="2" Text="{Binding State}" Grid.Column="1"/>
<TextBlock Margin="2" Text="{Binding Selection}" Grid.Column="2"/>
<TextBlock Margin="2" Text="{Binding FuelPumped}" Grid.Column="3"/>
<TextBlock Margin="2" Text="{Binding FuelCost}" Grid.Column="4"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
我在后面的代码中有这个声明,以便为集合设置资源:
public static ObservableCollection<PumpItem> PumpCollection
{
get { return pumpCollection; }
}
在我的 `MainWindow() 构造函数中,我设置了:
this.DataContext = this;
在 InitialiseComponent(); and my background worker thread to receive network inputs to update the list:
worker.RunWorkerAsync() 之前;`
此后台线程然后循环不断更新流中的集合并调用资源更新:
private void worker_DoWork(object sender, DoWorkEventArgs e)
{
//background tasks
Thread.Sleep(500); //allows the ui time to update and initialise
string s_decryptedMessage = string.Empty;
App.Current.Dispatcher.Invoke((Action)(() =>
{
Resources["PumpCollection"] = pumpCollection;
}));
while (true)
{
byteMessage = Recieve(stream);//get the number of pumps about to be recieved
Interact(byteMessage); //signal server to update pumplist
}
}
如果有帮助,我的 class 代码是:
namespace PoSClientWPF
{ public 枚举 pumpState { 可用的, 等待, 抽水, 支付中 };
public enum fuelSelection
{
Petrol,
Diesel,
LPG,
Hydrogen,
None
};
public class PumpItem
{
private string pumpID;
public string PumpID
{
get
{
return pumpID;
}
set
{
pumpID = value;
}
}
private double fuelPumped;
public double FuelPumped
{
get
{
return fuelPumped;
}
set
{
fuelPumped = value;
}
}
private double fuelCost;
public double FuelCost
{
get
{
return fuelCost;
}
set
{
fuelCost = Math.Round(value, 2); //cost to two DP
}
}
private fuelSelection selection;
public fuelSelection Selection
{
get
{
return selection;
}
set
{
selection = value;
}
}
private pumpState state;
public pumpState State
{
get
{
return state;
}
set
{
state = value;
}
}
public PumpItem(string _ID, pumpState _state, fuelSelection _selection)
{
this.pumpID = _ID;
this.FuelPumped = 0;
this.FuelCost = 0;
this.Selection = _selection;
this.State = _state;
}
}
}
正如我所说,我是 WPF 的新手,因此非常感谢任何指导或解决方案。谢谢。
Ash 完全正确,但这里有一个快速示例供您略读。这是一个 ViewModelBase 的示例,通常所有 ViewModel 都继承自该示例。来自我的一个回购协议。这就是您调用 OnChangedEvent 的方式。
private sample _Item;
public sample Item
{
get
{
return _Item;
}
set
{
if (_Item != value)
{
_Item = value;
OnPropertyChanged("Item");
}
}
}
这将在属性更改时更新所有内容。