我在SO上尝试了很多解决方案,但没有一个适合我。 DataGrid永远不会更新。
我有一个类(UserTab)从UserControl继承了XAML,一个类带有数据(TableController)。
XAML(UserTab):
<local:BaseTab.Resources>
<ResourceDictionary>
<controller:TableController x:Key="tablecontroller" />
</ResourceDictionary>
</local:BaseTab.Resources>
<DataGrid x:Name="dataGrid"
IsReadOnly="True"
ItemsSource="{Binding Path=FilteredEntries, Source={StaticResource tablecontroller}}"
SelectionUnit="Cell"
AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding id}"
Header="{StaticResource id}" />
<DataGridTextColumn Binding="{Binding name}"
Header="{StaticResource name}" />
<DataGridTextColumn Binding="{Binding desc}"
Header="{StaticResource desc}" />
</DataGrid.Columns>
</DataGrid>
我也尝试过更改Mode
或UpdateSourceTrigger
。
TableController
public class TableController : INotifyPropertyChanged
{
private IList<entry> _allEntries;
private BindingList<entry> _filteredEntries = new BindingList<entry>();
public IList<entry> AllEntries
{
get
{
return _allEntries;
}
set
{
_allEntries = value;
}
}
public BindingList<entry> FilteredEntries
{
get
{
return _filteredEntries;
}
set
{
_filteredEntries = value;
NotifyPropertyChanged("FilteredEntries");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void LoadData()
{
using (var dbContext = new InventarDBEntities())
{
AllEntries = dbContext.entry.OrderBy(x => x.name).ToList();
//FilteredEntries = new BindingList<entry>(AllEntries);
}
}
public void TestMethod()
{
foreach (entry entry in AllEntries)
{
FilteredEntries.Add(entry);
}
}
}
FilteredEntries
以后只包含AllEntries的子列表。我用这段代码来测试绑定。第一个FilteredEntries
为空,DataGrid也为空。单击按钮并触发TestMethod
FilteredEntries
包含条目,但DataGrid仍为空。我还尝试了ObservableCollection
并在UserTab.xaml.cs
中创建了一个属性,只是从FilteredEntries
转发TableController
。没有任何效果。
更新 似乎第一个Binding不起作用,因为当我通过代码设置ItemSource时,它会在更改List时更新。
答案 0 :(得分:1)
将FilteredEntries
属性的类型更改为ObservableCollection<entry>
,并在NotifyPropertyChanged
属性的设置器中调用AllEntries
方法:
public class TableController : INotifyPropertyChanged
{
private IList<entry> _allEntries;
private ObservableCollection<entry> _filteredEntries = new ObservableCollection<entry>();
public IList<entry> AllEntries
{
get
{
return _allEntries;
}
set
{
_allEntries = value;
NotifyPropertyChanged("AllEntries");
}
}
public ObservableCollection<entry> FilteredEntries
{
get
{
return _filteredEntries;
}
set
{
_filteredEntries = value;
NotifyPropertyChanged("FilteredEntries");
}
}
public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
private void LoadData()
{
using (var dbContext = new InventarDBEntities())
{
AllEntries = dbContext.entry.OrderBy(x => x.name).ToList();
//FilteredEntries = new BindingList<entry>(AllEntries);
}
}
public void TestMethod()
{
foreach (entry entry in AllEntries)
{
FilteredEntries.Add(entry);
}
}
}
这不起作用。它必须是绑定而不是更新。当我将dataGrid的dataContext设置为TableController.FilteredEntries时,它可以工作并显示所有更新
当然,您必须将DataContext
或其任何父元素的DataGrid
设置为TableController
类的实例,以便能够绑定到它。
我不知道你为什么要绑定资源。您不应将TableController
添加为资源,而是将其设置为元素的DataContext
:
<local:BaseTab.DataContext>
<controller:TableController />
</local:BaseTab.Resources>
<DataGrid x:Name="dataGrid"
IsReadOnly="True"
ItemsSource="{Binding Path=FilteredEntries}"
SelectionUnit="Cell"
AutoGenerateColumns="False">
...
或者:
<DataGrid x:Name="dataGrid"
IsReadOnly="True"
ItemsSource="{Binding Path=FilteredEntries}"
SelectionUnit="Cell"
AutoGenerateColumns="False">
<DataGrid.DataContext>
<controller:TableController />
</DataGrid.DataContext>
...
</DataGrid>