问题
All, I have recently had a problem where the visuals of a DataGrid
were not updating when the selected rows were scrolled (WPF DataGrid Column Becoming Corrupt when using Multi-Selection) which was solved using the method in the linked answer.
I have a TextBlock
in a StatusBar
and I bind this to an IsSelected
property to the required ViewModel. I thought that a solution to the question above would also solve the fact that the selected row count was not being updated correctly; that is, it updates fine when the DataGrid
scroll bar does not move, but when the bar does move, the TextBlock
fails to update as the OnPropertyChanged
event is not fired. I have check lots of posts on this and set the IsAsync=true
which did help in making the selection correct (it was 1 out before this update). The relevant XMAL is
<DataGrid Grid.Row="1" AlternatingRowBackground="Gainsboro" AlternationCount="2"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
AutoGenerateColumns="False" RowHeaderWidth="0" IsReadOnly="True"
CanUserAddRows="False" CanUserDeleteRows="False" SelectionMode="Extended"
EnableRowVirtualization="True" EnableColumnVirtualization="True"
ItemsSource="{Binding Cultures, NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged, IsAsync=True}"
dataAccess:MultiSelectItem.IsEnabled="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Code" Binding="{Binding Code}" IsReadOnly="True"/>
<DataGridTextColumn Header="Language" Binding="{Binding Language}" IsReadOnly="True"/>
<DataGridTextColumn Header="LocalName" Binding="{Binding LocalName}" IsReadOnly="True"/>
</DataGrid.Columns>
</DataGrid>
<StatusBar Grid.Row="1" Margin="0,0.4,0.4,-0.4">
<StatusBarItem DockPanel.Dock="Left" Background="#FF007ACC" Margin="0,2,0,0">
<TextBlock Text="{Binding TotalSelectedCultures}" Margin="5,0,0,0" Foreground="White"/>
</StatusBarItem>
</StatusBar>
Where the view model that this links to is
public class CultureDataViewModel : ViewModelBase
{
public enum FilterType
{
AllCultures,
NeutralCultures,
SpecificCultures
};
public FilterType SelectedFilterType { get; private set; }
public ICollectionView CulturesView { get; private set; }
public MultiSelectCollectionView<CultureViewModel> Cultures { get; private set; }
public CultureDataViewModel()
{
SelectedFilterType = FilterType.AllCultures;
LoadCultures();
}
void OnCultureViewModelPropertyChanged(object sender, PropertyChangedEventArgs e)
{
string IsSelected = "IsSelected";
(sender as CultureViewModel).VerifyPropertyName(IsSelected);
if (e.PropertyName == IsSelected)
this.OnPropertyChanged("TotalSelectedCultures");
}
void OnCollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null && e.NewItems.Count != 0)
foreach (CultureViewModel cultVm in e.NewItems)
cultVm.PropertyChanged += this.OnCultureViewModelPropertyChanged;
if (e.OldItems != null && e.OldItems.Count != 0)
foreach (CultureViewModel cultVm in e.OldItems)
cultVm.PropertyChanged -= this.OnCultureViewModelPropertyChanged;
}
/// <summary>
/// Load the avalible cultures depending on filter selection
/// </summary>
public void LoadCultures()
{
// Get data...
}
/// <summary>
/// Hold the current total selected cultures to add to the resource
/// data set.
/// </summary>
public string TotalSelectedCultures
{
get
{
int selectedCultures = this.Cultures.SelectedItems.Count;
return String.Format("{0:n0} of {1:n0} cultures selected",
selectedCultures,
Cultures.Count);
}
}
}
TotalSelectedCultures
stops updating when the DataGrid
scrolls, how do I stop this and allow the row count to display even in this case?
Thanks for your time.
回答1:
Can you simply attach to the SelectedItems.CollectionChanged event inside LoadCultures()?
Cultures.SelectedItems.CollectionChanged += SelectedItems_CollectionChanged;
void SelectedItems_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.RaisePropertyChanged("TotalSelectedCultures");
}
来源:https://stackoverflow.com/questions/17537276/binding-selected-rowcount-to-textblock-not-firing-onpropertychanged-after-datagr