Reputation: 7293
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" />
Upvotes: 2
Views: 182
Reputation: 13188
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);
}
}
Upvotes: 2
Reputation: 5691
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.
Upvotes: 0