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

如何在不同类中使用已创建的列表?附列表创建代码实现

How to Use Lists Created in a Button Click Event in Other Classes

Hey, let's work through this problem. Right now your Item_Name, Sell_Price, and Buy_Price lists are local variables inside the Skills_Button_Click method—meaning their scope is limited to that method alone, so other classes can't reach them. To fix this, we need to adjust how we store or pass these lists. Here are a few practical solutions tailored to different scenarios:

1. Promote Lists to Class-Level Members (Most Direct)

Move the lists from the method to the top of your window/user control class, then wrap them in read-only properties to control access. This keeps your data encapsulated while letting other classes read it:

// Example class name—replace with your actual window/user control class
public class SkillWindow : Window
{
    // Private backing fields to store the lists
    private List<string> _itemNames = new List<string>();
    private List<double> _sellPrices = new List<double>();
    private List<double> _buyPrices = new List<double>();

    // Public read-only properties so other classes can't modify the lists directly
    public IReadOnlyList<string> ItemNames => _itemNames.AsReadOnly();
    public IReadOnlyList<double> SellPrices => _sellPrices.AsReadOnly();
    public IReadOnlyList<double> BuyPrices => _buyPrices.AsReadOnly();

    private void Skills_Button_Click(object sender, RoutedEventArgs e)
    {
        // Clear old data first to avoid duplicate entries
        _itemNames.Clear();
        _sellPrices.Clear();
        _buyPrices.Clear();

        var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(Database);
        foreach (var key in dict.Keys)
        {
            _itemNames.Add(dict[key].name);
            _sellPrices.Add(Convert.ToDouble(dict[key].sell_average));
            _buyPrices.Add(Convert.ToDouble(dict[key].buy_average)); // Filling in your incomplete line
        }
    }
}

To access these lists in another class, you'll need a reference to an instance of SkillWindow. For example, if the window is already open:

// Get the open SkillWindow instance
var skillWindow = Application.Current.Windows.OfType<SkillWindow>().FirstOrDefault();
if (skillWindow != null)
{
    // Use the lists
    foreach (var name in skillWindow.ItemNames)
    {
        Console.WriteLine($"Item: {name}");
    }
}

2. Pass Data via Events (Great for Notifying Other Classes When Data Loads)

If you only need other classes to get the data once it's finished loading, define a custom event to broadcast the data when the button click completes:

public class SkillWindow : Window
{
    // Custom event to notify listeners when skills data is loaded
    public event EventHandler<SkillsDataLoadedEventArgs> SkillsDataLoaded;

    private void Skills_Button_Click(object sender, RoutedEventArgs e)
    {
        var itemNames = new List<string>();
        var sellPrices = new List<double>();
        var buyPrices = new List<double>();

        var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(Database);
        foreach (var key in dict.Keys)
        {
            itemNames.Add(dict[key].name);
            sellPrices.Add(Convert.ToDouble(dict[key].sell_average));
            buyPrices.Add(Convert.ToDouble(dict[key].buy_average));
        }

        // Trigger the event to send data to subscribed classes
        SkillsDataLoaded?.Invoke(this, new SkillsDataLoadedEventArgs(itemNames, sellPrices, buyPrices));
    }
}

// Custom event args to carry the loaded data
public class SkillsDataLoadedEventArgs : EventArgs
{
    public IReadOnlyList<string> ItemNames { get; }
    public IReadOnlyList<double> SellPrices { get; }
    public IReadOnlyList<double> BuyPrices { get; }

    public SkillsDataLoadedEventArgs(List<string> itemNames, List<double> sellPrices, List<double> buyPrices)
    {
        ItemNames = itemNames.AsReadOnly();
        SellPrices = sellPrices.AsReadOnly();
        BuyPrices = buyPrices.AsReadOnly();
    }
}

Then in another class, subscribe to the event to receive the data:

public class AnotherWindow : Window
{
    public AnotherWindow(SkillWindow skillWindow)
    {
        InitializeComponent();
        // Subscribe to the data loaded event
        skillWindow.SkillsDataLoaded += SkillWindow_OnSkillsDataLoaded;
    }

    private void SkillWindow_OnSkillsDataLoaded(object sender, SkillsDataLoadedEventArgs e)
    {
        // Now you can use the loaded data here
        var loadedItems = e.ItemNames;
        // ... do your business logic with the lists
    }
}

If you're building a WPF app, using the MVVM pattern will make sharing data between classes (especially UI classes) much cleaner. Move your data to a ViewModel, then let multiple UI components bind to it:

// ViewModel class with observable collections for UI binding
public class SkillsViewModel : INotifyPropertyChanged
{
    private ObservableCollection<string> _itemNames = new ObservableCollection<string>();
    private ObservableCollection<double> _sellPrices = new ObservableCollection<double>();
    private ObservableCollection<double> _buyPrices = new ObservableCollection<double>();

    public ObservableCollection<string> ItemNames
    {
        get => _itemNames;
        set
        {
            _itemNames = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<double> SellPrices
    {
        get => _sellPrices;
        set
        {
            _sellPrices = value;
            OnPropertyChanged();
        }
    }

    public ObservableCollection<double> BuyPrices
    {
        get => _buyPrices;
        set
        {
            _buyPrices = value;
            OnPropertyChanged();
        }
    }

    // Method to load data (moved from the button click event)
    public void LoadSkillsData(string databaseJson)
    {
        ItemNames.Clear();
        SellPrices.Clear();
        BuyPrices.Clear();

        var dict = JsonConvert.DeserializeObject<Dictionary<string, Item>>(databaseJson);
        foreach (var key in dict.Keys)
        {
            ItemNames.Add(dict[key].name);
            SellPrices.Add(Convert.ToDouble(dict[key].sell_average));
            BuyPrices.Add(Convert.ToDouble(dict[key].buy_average));
        }
    }

    // Implement INotifyPropertyChanged to update the UI when data changes
    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

Update your button's class to use the ViewModel:

public class SkillWindow : Window
{
    private readonly SkillsViewModel _viewModel;

    public SkillWindow(SkillsViewModel viewModel)
    {
        InitializeComponent();
        _viewModel = viewModel;
        DataContext = _viewModel; // Bind the window to the ViewModel
    }

    private void Skills_Button_Click(object sender, RoutedEventArgs e)
    {
        // Call the ViewModel's load method
        _viewModel.LoadSkillsData(Database);
    }
}

Now any other UI class can bind to the same ViewModel instance. For example, in another window's XAML:

<!-- Bind a ListBox to the ItemNames collection -->
<ListBox ItemsSource="{Binding ItemNames}" DisplayMemberPath="." />

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.25 07:30:39