2016-04-19 37 views
0

我是WPF的新手,所以可能会非常简单,我错过了。Databound列表框不更新到可观察集合的正确值WPF

我有一个列表框,它是从static observableCollection<myClass>持有databound类属性。该集合每秒从网络流源更新几次,从调试中我可以看出,集合正在更新。声明如下:static ObservableCollection<PumpItem> pumpCollection = new ObservableCollection<PumpItem>();其中PumpItem是我班的名字。

这并不是说列表框没有显示任何东西,但它正在更新以显示添加到集合中的任何新值,但这些值只反映了它们进入集合的第一刻的属性。

列表框的值被绑定为这样:

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

     } 

在我`主窗口( )构造函数我已经设置:

this.DataContext = this; 

之前InitialiseComponent(); and my background worker thread to receive network inputs to update the list: worker.RunWorker异步();`

这个后台线程然后循环不断地从流将更新集合,并调用资源更新:

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 

     } 
} 

如果有帮助,我的类代码是这样的:

namespace PoSClientWPF 

{ 公共枚举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所以将不胜感激任何指导或解决方案。谢谢。

+1

'这些只反映了他们进入集合的第一刻的属性。通知ui关于viewModel(在PumpItem中)变化的最简单方法是在PumpItem中实现'INotifyPropertyChanged'并在setter中引发OnPropertyChanged事件 – ASh

+0

为什么你的PumpCollection是静态的?这是设计决定,还是试图让绑定工作? –

+0

@MattWilkinson你得到了我,认为这是一种绝望的行为。想不到为什么我需要静态的任何理由。所以回到公共场合吧。 (如果您引用了get方法PumpCollection,而不是我想要静态的实际pumpCollection集合。 – James

回答

1

灰是完全正确的,但这里是一个简单的例子,您可以浏览。这是典型的所有ViewModel继承的ViewModelBase的示例。从我的回购之一。这你将如何调用你的OnChangedEvent。

private sample _Item; 
    public sample Item 
    { 
     get 
     { 
      return _Item; 
     } 
     set 
     { 
      if (_Item != value) 
      { 
       _Item = value; 
       OnPropertyChanged("Item"); 
      } 
     } 
    } 

这会得到它更新所有属性更改时的位置。

+0

我确实最终走下了这条路,并设法获得了所需的功能。还要感谢这个非常有用的文章http://www.blackwasp.co.uk/INotifyPropertyChanged.aspx – James

相关问题