You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Xamarin中从DialogFragment更新DB记录后刷新ListView与图表

嘿,这个场景我在做Xamarin Android项目时太熟悉了!核心就是数据更新完成后,通知UI层重新拉取最新数据并刷新对应的控件,下面给你一步步拆解实现方案,都是我实战验证过的:

核心思路

把数据获取、ListView刷新、图表刷新的逻辑分别封装成独立方法,然后在数据库更新完成的时机(Dialog保存操作后),统一调用这些刷新方法,确保两个控件都基于最新数据渲染。

具体实现步骤

1. 抽象数据获取逻辑

先把从SQLite读取产品数据的代码抽成单独方法,避免重复写查询逻辑,保证ListView和图表用的是同一套数据源:

// 假设你的产品实体类是Product,包含Id、Name、Quantity等字段
private List<Product> FetchLatestProductData()
{
    string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Products.db3");
    using (var dbConnection = new SQLiteConnection(dbPath))
    {
        // 这里写你的查询逻辑,比如获取所有产品
        return dbConnection.Table<Product>().ToList();
    }
}

2. 封装ListView刷新方法

不管是初始化还是后续刷新,都调用这个方法来更新ListView的内容:

// 假设你已经在MainActivity里初始化了ListView和对应的Adapter(比如ArrayAdapter或自定义BaseAdapter)
private ArrayAdapter<Product> _productAdapter;
private ListView _productListView;

private void RefreshProductListView()
{
    var latestProducts = FetchLatestProductData();
    
    // 如果是ArrayAdapter:清空旧数据,添加新数据,通知数据源变化
    _productAdapter.Clear();
    _productAdapter.AddAll(latestProducts);
    _productAdapter.NotifyDataSetChanged();
    
    // 如果是自定义BaseAdapter:更新Adapter内部的数据源,再通知变化
    // _customProductAdapter.UpdateDataSource(latestProducts);
    // _customProductAdapter.NotifyDataSetChanged();
}

3. 封装OxyPlot图表刷新方法

同样,把图表数据更新和刷新的逻辑封装起来,确保每次都用最新的产品数量生成柱状图:

// 假设你已经初始化了PlotView和ColumnSeries
private PlotView _productQuantityPlot;
private ColumnSeries _quantityColumnSeries;
private CategoryAxis _xAxis; // 用于显示产品名称的X轴

private void RefreshProductChart()
{
    var latestProducts = FetchLatestProductData();
    
    // 清空旧的柱状图数据
    _quantityColumnSeries.Items.Clear();
    // 清空旧的X轴标签
    _xAxis.Labels.Clear();
    
    // 遍历最新数据,填充柱状图和X轴标签
    foreach (var product in latestProducts)
    {
        _quantityColumnSeries.Items.Add(new ColumnItem(product.Quantity));
        _xAxis.Labels.Add(product.Name);
    }
    
    // 通知OxyPlot刷新图表
    _productQuantityPlot.Model.InvalidatePlot(true);
}

4. 在DialogFragment更新数据库后触发同步刷新

这里推荐用事件回调的方式,让DialogFragment在数据更新完成后通知MainActivity执行刷新,这样更灵活(只有真正更新了数据才刷新,而不是每次关闭Dialog都刷新):

第一步:在DialogFragment里定义事件

public class ProductEditDialog : DialogFragment
{
    // 定义事件,用于通知宿主Activity数据已更新
    public event Action OnProductDataUpdated;
    
    // 假设这是保存按钮的点击事件
    private void OnSaveButtonClicked(object sender, EventArgs e)
    {
        // 1. 获取表单输入的内容(比如产品名称、数量)
        // 2. 执行SQLite的新增/更新操作
        string dbPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), "Products.db3");
        using (var dbConnection = new SQLiteConnection(dbPath))
        {
            dbConnection.InsertOrUpdate(_currentProduct); // _currentProduct是要保存的产品对象
        }
        
        // 3. 触发事件,通知MainActivity刷新UI
        OnProductDataUpdated?.Invoke();
        
        // 关闭Dialog
        Dismiss();
    }
}

第二步:在MainActivity里订阅事件并执行刷新

// 显示DialogFragment的代码
private void ShowProductEditDialog()
{
    var editDialog = new ProductEditDialog();
    // 订阅数据更新事件
    editDialog.OnProductDataUpdated += () =>
    {
        // 回到主线程刷新UI(如果数据库操作在后台线程的话必须加这个)
        RunOnUiThread(() =>
        {
            RefreshProductListView();
            RefreshProductChart();
        });
    };
    editDialog.Show(SupportFragmentManager, "ProductEditDialog");
}
额外注意事项
  • 如果你的数据库操作是在后台线程执行的(推荐这么做,避免阻塞UI),一定要用RunOnUiThread把刷新UI的逻辑切回主线程,否则会抛出跨线程操作UI的异常。
  • 如果后续想优化,可以考虑引入MVVM模式,用ObservableCollection<Product>作为数据源,这样数据源变化时ListView可以自动刷新,图表也可以监听集合变化来自动更新,代码会更简洁。

内容的提问来源于stack exchange,提问作者opt

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 08:50:58