【问题标题】:DataBinding for DataGrid not working?DataGrid 的数据绑定不起作用?
【发布时间】:2015-08-02 04:26:54
【问题描述】:

我正在使用在一个简单 WPF 应用程序的 MainWindow 类中定义的ObservableCollection。出于某种原因,列表会更新(我可以在调试时看到),但是 UI 没有更新。

现在,如果我创建一个Timer 并循环它,我可以通过设置ItemSource 来更新DataGrid。这可行,但会导致我的 DataGrid 出现可怕的闪烁。

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

进一步深入我的代码,我使用这一行来实际更新或添加数据到列表中。

calculatedData = await CalculateData();

CalculateData函数定义如下:

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

对于我的xaml,我有一个简单的 DataGrid,如下所示:

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

问题:为什么 DataGrid 没有更新?由于我没有重新绑定,这会解决我的闪烁问题吗?

-

更新

我什至将我的主要声明更改为以下内容(因为我看到它这样做了),但我仍然没有让它工作。

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" />

【问题讨论】:

  • “dataGrid_AutoGeneratingColumn”中发生了什么?
  • @Sajeetharan 好问题!我正在删除某个列,只是重命名其他列标题。所以,没有什么不寻常的。

标签: c# wpf xaml data-binding datagrid


【解决方案1】:

如果你只是这样做:

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

它会起作用的。我猜你的 XAML 绑定可能不起作用,因为 DataContext 没有定义。

编辑:这是完整的代码,

主窗口:

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>

结果:

编辑 2:添加了一个按钮并稍微移动了一些代码,以便您进行测试。

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);
    }
}

【讨论】:

  • 在我的 MainWindow 构造函数中,我添加了 DataContext = this; 并获得了列标题,但仍然没有数据??
  • 你甚至不需要 DataContext。我会用完整的代码编辑我的答案。
  • 我做的和你做的一样,但是在一个计时器滴答功能中。但是,这会导致我的 DataGrid 出现可怕的闪烁。这就是我试图避免的。 (以及在每个刻度上设置 itemsource)。
  • 定时器可能导致闪烁。但是你也不需要计时器。看看我发布的完整代码。
  • 行得通!但为什么我的 XAML 绑定不起作用?我是否必须实现ObservableCollection 而不是一个简单的列表?
【解决方案2】:

每次尝试从 CalculateData() 的结果中添加项目时,您都在替换项目源;

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

也不确定您是否在构造函数中初始化了 CalculatedData 属性。

CalculatedData = new ObservableCollection<yourType>();

让我知道这是否有效。

【讨论】:

  • 这对我仍然不起作用。这些项目在我的列表中,但 UI 永远不会更新,我的数据网格只是空白(甚至没有显示标题列)。
猜你喜欢
  • 2016-05-22
  • 2023-03-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-12-16
  • 2017-12-11
  • 1970-01-01
相关资源
最近更新 更多