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

WPF分页与未知数量元素事件处理 修复Shopify集成应用内存泄漏

WPF跨用户控件通信与分页逻辑实现方案

方案1:依赖属性+路由事件(低耦合官方推荐方案)

该方案符合WPF设计规范,无需额外引入架构依赖,适合中小型项目快速实现:

  1. 改造旧商品视图UC的代码:
// 旧商品视图UC(OldProductView.xaml.cs)
// 1. 注册下一页点击路由事件
public static readonly RoutedEvent NextPageClickedEvent = EventManager.RegisterRoutedEvent(
    "NextPageClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(OldProductView));
public event RoutedEventHandler NextPageClicked
{
    add { AddHandler(NextPageClickedEvent, value); }
    remove { RemoveHandler(NextPageClickedEvent, value); }
}
// 2. 注册上一页点击路由事件
public static readonly RoutedEvent PrevPageClickedEvent = EventManager.RegisterRoutedEvent(
    "PrevPageClicked", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(OldProductView));
public event RoutedEventHandler PrevPageClicked
{
    add { AddHandler(PrevPageClickedEvent, value); }
    remove { RemoveHandler(PrevPageClickedEvent, value); }
}
// 3. 公开商品ID列表依赖属性,接收容器UC传递的待展示商品ID
public static readonly DependencyProperty CurrentProductIdsProperty = DependencyProperty.Register(
    "CurrentProductIds", typeof(List<long>), typeof(OldProductView), new PropertyMetadata(default, OnProductIdsChanged));
public List<long> CurrentProductIds
{
    get => (List<long>)GetValue(CurrentProductIdsProperty);
    set => SetValue(CurrentProductIdsProperty, value);
}
// ID变更时自动触发原有商品渲染逻辑
private static void OnProductIdsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is OldProductView view && e.NewValue is List<long> ids)
    {
        view.FillProductItems(ids); // 调用你已有填充子控件的方法
    }
}
// 原有导航按钮点击事件仅抛出路由事件,不处理业务逻辑
private void BtnNextPage_OnClick(object sender, RoutedEventArgs e)
{
    RaiseEvent(new RoutedEventArgs(NextPageClickedEvent));
}
private void BtnPrevPage_OnClick(object sender, RoutedEventArgs e)
{
    RaiseEvent(new RoutedEventArgs(PrevPageClickedEvent));
}
  1. 在容器UC中引用并绑定旧UC的事件:
<!-- 容器UC(ProductContainerView.xaml) -->
<UserControl x:Class="YourNamespace.ProductContainerView"
             xmlns:local="clr-namespace:YourNamespace">
    <Grid>
        <!-- 给旧UC设置x:Name,即可在后台代码中访问 -->
        <local:OldProductView x:Name="ProductViewCore" 
                              NextPageClicked="ProductViewCore_NextPageClicked"
                              PrevPageClicked="ProductViewCore_PrevPageClicked"/>
    </Grid>
</UserControl>
// 容器UC后台代码(ProductContainerView.xaml.cs)
// 处理下一页逻辑
private void ProductViewCore_NextPageClicked(object sender, RoutedEventArgs e)
{
    // 执行你已有的分页、预加载、资源释放逻辑
    CurrentPageIndex++;
    var targetPageIds = GetTargetPageProductIds(CurrentPageIndex);
    // 赋值触发旧UC自动重绘
    ProductViewCore.CurrentProductIds = targetPageIds;
}
// 处理上一页逻辑
private void ProductViewCore_PrevPageClicked(object sender, RoutedEventArgs e)
{
    if(CurrentPageIndex <= 0) return;
    CurrentPageIndex--;
    var targetPageIds = GetTargetPageProductIds(CurrentPageIndex);
    ProductViewCore.CurrentProductIds = targetPageIds;
}

方案2:消息通知(MVVM架构下完全解耦方案)

如果项目已使用MVVM架构,可通过全局消息总线实现完全解耦的通信:

// 实现轻量全局消息总线
public static class MessageBus
{
    private static readonly Dictionary<Type, List<Action<object>>> _subscribers = new();
    public static void Subscribe<T>(Action<T> handler)
    {
        var type = typeof(T);
        if (!_subscribers.ContainsKey(type))
            _subscribers[type] = new List<Action<object>>();
        _subscribers[type].Add(obj => handler((T)obj));
    }
    public static void Publish<T>(T message)
    {
        if (_subscribers.TryGetValue(typeof(T), out var handlers))
            handlers.ForEach(handler => handler(message));
    }
}
// 定义业务消息类
public class NextPageRequest { }
public class PrevPageRequest { }
public class UpdateProductPageMsg { public List<long> ProductIds { get; set; } }

旧UC按钮点击时发布消息:

private void BtnNextPage_OnClick(object sender, RoutedEventArgs e)
{
    MessageBus.Publish(new NextPageRequest());
}

容器UC订阅消息处理分页逻辑:

public ProductContainerView()
{
    InitializeComponent();
    MessageBus.Subscribe<NextPageRequest>(_ => 
    {
        CurrentPageIndex++;
        var ids = GetTargetPageProductIds(CurrentPageIndex);
        MessageBus.Publish(new UpdateProductPageMsg { ProductIds = ids });
    });
}

旧UC订阅更新消息刷新视图:

public OldProductView()
{
    InitializeComponent();
    MessageBus.Subscribe<UpdateProductPageMsg>(msg => FillProductItems(msg.ProductIds));
}

注意事项

  • 使用消息总线方案时,控件销毁前要取消对应消息的订阅,避免产生新的内存泄漏
  • 路由事件方案适合控件层级简单的场景,调试成本更低,更适合WPF新手快速落地
  • 初始加载完成后直接给旧UC的CurrentProductIds赋值即可触发首次渲染

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.06 08:18:01