Reputation: 6911
I need to take some action (e.g. make some cells readonly based on some other cells) after data biinding is completed. In WinForm DataGridView, I used to do it in DataBindingComplete event. However, I couldn't find such an event in WPF DataGrid. What else can I use?
Upvotes: 5
Views: 11142
Reputation: 4146
I wanted to color my rows depending on their property values, and I tried a lot of events (DataGrid.Initialized
, DataContextChanged
, AddingNewItem
, RowLoaded
etc.) along with the BeginInvoke
thing, but nothing worked. Then i found:
Loaded
This event did the trick, as it allowed me to iterate through my rows and color them as I wanted.
private void SubjectsList_Loaded(object sender, RoutedEventArgs e)
{
Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => ColorMyRows()));
}
The CollorMyRows
looks pretty similar to tihs:
private void ColorMyRows()
{
DataGridRow row = null;
for (int i = 0; i < SubjectsList.Items.Count; i++)
{
// get one row
row = SubjectsList.ItemContainerGenerator.ContainerFromIndex(i) as DataGridRow;
if (myConditionIsFulfilled)
{
row.Background = Brushes.PaleGoldenrod; // black'n gold baby
row.ToolTip = "This item fulfills the condition.";
}
else
{
row.Background = Brushes.PaleGreen;
row.ToolTip = "This item does not.";
}
}
}
Note: If You have an ObservableCollection
bound to a DataGrid
, the index in the loop (index of a DataGrid
's row) will correspond to the index in the collection :)
Upvotes: 2
Reputation: 1
You can declare a BackgroundWorker and try to fill your GridView in the DoWork event and write your code in the RunWorkerCompleted event
Upvotes: 0
Reputation: 618
you can bind cells readonly property to a property that changes when other properties of the model changes. I was thinking exactly like you while ago, but I started to think more in the model more than the view I am not interested in DataGrid but the list that is bounded to, you can do the same I used it before in a similar situation
public class Model : INotifyPropertyChanged
{
public bool IsChecked
{
get { return isChecked; }
set
{
isChecked = value;
RaisePropertyChanged("IsChecked");
RaisePropertyChanged("Visibilty");
}
}
public Visibility Visibilty
{
get
{
return IsChecked ? Visibility.Visible : Visibility.Hidden;
}
}
}
it was a checkbox in datagrid bound to IsChecked Property and other cells bounded to visibility and it worked for me. hope this help you.
Upvotes: 0
Reputation: 618
May be you are using threads and datagrid is not thread-safe as all UI components.
Upvotes: 1
Reputation: 6911
This is what I figured out: DataContextChanged event is the right event to use. The only problem is that the datagrid is not quite ready to be consumed in my code inside this event. However, it works fine if I use Dispatcher.BeginInvoke like this:
Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => DoSomethingWithGrid()));
Can anybody explain why this is necessary?
Actually, when dealing with WPF DataGrid, I had to use Dispatcher in quite a few cases in order to make it work. Why?
Upvotes: 8