数据绑定列表框未更新为可观察集合WPF中的正确值

时间:2016-04-19 18:34:54

标签: c# wpf data-binding listbox observablecollection

我是WPF的新手,所以可能是我错过的非常简单的事情。

我有一个列表框,它保存了static observableCollection<myClass>的数据绑定类属性。该集合每秒从网络流源更新几次,从我从调试中可以看出,该集合正在正确更新。声明如下: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; }

        }

在我的`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

        }
}

如果有帮助,我的班级代码是:

namespace PoSClientWPF

{     public enum 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 个答案:

答案 0 :(得分:1)

Ash完全正确,但这里有一个快速示例供您浏览。这是ViewModelBase的示例,通常所有ViewModel都继承自{{3}}。从我的一个回购。这就是你如何调用你的OnChangedEvent。

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

这将使您在属性更改时更新所有内容。