简体   繁体   中英

DataBinding for DataGrid not working?

I am using a ObservableCollection defined in my MainWindow classs of a simple WPF application. For some reason the list updates (I can see this when debugging), however the UI does not update.

Now, if I create a Timer and loop it, I can update the DataGrid by setting the ItemSource . This works, but causes a horrible flickering in my DataGrid.

public ObservableCollection<CalculatedData> calculatedData { get; set; }

Further down into my code, I use this line to actually update or add data to the list.

calculatedData = await CalculateData();

The CalculateData function is defined as follows:

private Task<ObservableCollection<CalculatedData>> CalculateData()
{
    return Task.Run(() =>
    {
        ObservableCollection<CalculatedData> cdList = new ObservableCollection<CalculatedData>();
        // Do a lot of stuff
        return cdList;
    });
}

For my xaml I have a simple DataGrid as shown below:

<DataGrid Name="dataGrid" ItemsSource="{Binding calculatedData}" IsReadOnly="True" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserSortColumns="False" CanUserResizeRows="False" AutoGeneratingColumn="dataGrid_AutoGeneratingColumn" />

Question: Why is the DataGrid not being upadted? Will this fix my flickering issue since i'm not re-binding?

-

UPDATE

I even changed my main declaration to the following (since Iv'e seen it done this way), but I have still not gotten it to work.

private ObservableCollection<CalculatedData> calculatedData = new ObservableCollection<CalculatedData>();
public ObservableCollection<CalculatedData> CalculatedData
{
    get { return calculatedData; }
    set
    {
        calculatedData = value;
    }
}

XAML:

<DataGrid Name="dataGrid" ItemsSource="{Binding CalculatedData}" IsReadOnly="True" CanUserReorderColumns="False" CanUserResizeColumns="False" CanUserSortColumns="False" CanUserResizeRows="False" AutoGeneratingColumn="dataGrid_AutoGeneratingColumn" />

If you simply do:

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        calculatedData = await CalculateData();
        dataGrid1.ItemsSource = calculatedData;
    }

it will work. I guess your XAML binding is probably not working because DataContext is not defined.

EDIT: Here's full code,

MainWindow:

public partial class MainWindow : Window
{
    public ObservableCollection<CalculatedData> calculatedData { get; set; }

    public MainWindow()
    {
        InitializeComponent();
    }

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        calculatedData = await CalculateData();
        dataGrid1.ItemsSource = calculatedData;
    }

    private Task<ObservableCollection<CalculatedData>> CalculateData()
    {
        return Task.Run(() =>
        {
            ObservableCollection<CalculatedData> cdList = new ObservableCollection<CalculatedData>();

            // Do a lot of stuff
            cdList.Add(new CalculatedData { Data1 = 1, Data2 = 2, Data3 = 3 });
            cdList.Add(new CalculatedData { Data1 = 1, Data2 = 2, Data3 = 3 });
            cdList.Add(new CalculatedData { Data1 = 1, Data2 = 2, Data3 = 3 });
            cdList.Add(new CalculatedData { Data1 = 1, Data2 = 2, Data3 = 3 });
            cdList.Add(new CalculatedData { Data1 = 1, Data2 = 2, Data3 = 3 });

            return cdList;
        });
    }
}

XAML:

<Grid>
    <DataGrid x:Name="dataGrid1" Margin="0" />
</Grid>

Result:

在此处输入图片说明

EDIT 2: added a button and moved code around a little so you can test.

public partial class MainWindow : Window
{
    public ObservableCollection<CalculatedData> calculatedData { get; set; }
    int i;

    public MainWindow()
    {
        InitializeComponent();

        //initialize your binding collection
        calculatedData = new ObservableCollection<CalculatedData>();
    }

    private async void Window_Loaded(object sender, RoutedEventArgs e)
    {
        i = 1;
        //create initial data and bind to data grid
        calculatedData = await CalculateData();
        dataGrid1.ItemsSource = calculatedData;
    }

    private Task<ObservableCollection<CalculatedData>> CalculateData()
    {
        return Task.Run(() =>
        {
            ObservableCollection<CalculatedData> cdList = new ObservableCollection<CalculatedData>();

            // Do a lot of stuff
            for (int j = 0; j < 5; j++)
            {
                cdList.Add(new CalculatedData { Data1 = i, Data2 = i + 1, Data3 = i + 2 });
                i++;
            }

            return cdList;
        });
    }
    private async void button1_Click(object sender, RoutedEventArgs e)
    {
        //place new data in a temporary collection
        ObservableCollection<CalculatedData> newData = await CalculateData();

        //add new data to the collection bound to the data grid
        //preferably, don't just replace it
        //any business logic you may need for adding, 
        //deleting, filtering data, etc goes here 
        foreach (CalculatedData cd in newData)
            calculatedData.Add(cd);
    }
}

You are replacing the items source each time try adding items from result of CalculateData();

var data = await CalculateData();
foreach(var d in data)
   calculatedData.Add(d);

also not sure if you are initialized your CalculatedData property init in constructor.

CalculatedData = new ObservableCollection<yourType>();

let me know if this works.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM