【问题标题】:Change the value of Dictionary based on the SelectedItem in ListBox根据 ListBox 中的 SelectedItem 改变 Dictionary 的值
【发布时间】:2020-03-08 07:40:52
【问题描述】:

My TextBox 显示了一个类的属性值,该属性值根据 ListBox 中的 SelectedItem 进行更改。 (到目前为止,一切都很好。)但是,现在我想用用户指定的值替换 Dictionary 中定义的值(key 是 ListBox 中的 SelectedItem)。这不起作用,无论我做什么。它只是抛出一个异常。这是我的完整代码:

MainWindow.xaml.cs

using ChangeTextBoxBasedOnListBox.Model;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
using System.Windows.Controls;

public partial class MainWindow : Window
    {
        ObservableCollection<string> oc;
        ObservableCollection<Graph> graph;
        Dictionary<string, Graph> dic = new Dictionary<string, Graph>();
        ListBox lB;

        public MainWindow()
        {
            InitializeComponent();

            oc = new ObservableCollection<string>()
            {
                "Test_1",
                "Test_2"
            };

            graph = new ObservableCollection<Graph>()
            {
                new Graph(10),
                new Graph(100)
            };

            listBox.ItemsSource = oc;

            foreach (var test in oc.Select((k, i) => new { kvp = k, index = i }))
            {
                dic.Add(test.kvp, graph[test.index]);
            }
        }

        private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Graph dicValue = dic[(sender as ListBox).SelectedItem.ToString()];
            textBox.Text = Convert.ToString(dicValue.Step);
        }

        private void textBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            // This works, but this isn't what I want to do
            if (dic.ContainsKey("Test_1"))
                dic["Test_1"].Step = 1000;

            // What I want to do is:
            // (dic[(The current SelectedItem in ListBox)].Step  = (The value user specified)

            // This doesn't work ... throws an exception
            //if (lB.SelectedItem != null)
            //{
            //    if (dic.ContainsKey(lB.SelectedItem.ToString()))
            //    {
            //        dic[lB.SelectedItem.ToString()].Step = (sender as Graph).Step;
            //    }
            //}
        }
    }
}

MainWindow.xaml

<Window x:Class="ChangeTextBoxBasedOnListBox.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:ChangeTextBoxBasedOnListBox"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <ListBox x:Name="listBox" HorizontalAlignment="Left" Height="238" Margin="88,82,0,0" VerticalAlignment="Top" Width="288" SelectionChanged="listBox_SelectionChanged"/>
        <TextBox x:Name="textBox" HorizontalAlignment="Left" Height="23" Margin="523,82,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" TextChanged="textBox_TextChanged"/>

    </Grid>
</Window>

Model/Graph.cs

namespace ChangeTextBoxBasedOnListBox.Model
{
    public class Graph
    {
        public Graph(int step) { Step = step; }

        public int Step { get; set; }
    }
}

...我想我只需要再走一步,但我找不到路。请帮我。提前谢谢你。

【问题讨论】:

  • 请注意,对于 ocgraph 变量的类型使用 ObservableCollection 是没有意义的。没有任何东西可以观察到集合的变化。它们可以是简单的数组。
  • @Clemens:我明白了,谢谢。也许,下次我会让他们List&lt;&gt;,而不是ObservableCollection&lt;&gt;。 (应该没问题吧?)
  • 当然(sender as Graph) 始终为null,因为sender 是一个TextBox。
  • @Clemens 哎呀,我不知道……那么,如何使用sender(或任何其他方式)在 TextBox 中获取用户输入?
  • @Clemens 哦,有道理,谢谢。让我纠正一件事:我应该在listBox_SelectionChanged() 中添加lB = sender as ListBox;。而且,根据你的建议,我应该这样写:if (lB.SelectedItem != null) { if (dic.ContainsKey(lB.SelectedItem.ToString())) { dic[lB.SelectedItem.ToString()].Step = Convert.ToInt32(((TextBox)sender).Text); } }。但是,它仍然给我一个例外......有什么办法可以解决这个问题?

标签: c# wpf dictionary textbox listbox


【解决方案1】:

你的方法太复杂了。实际上,您根本不需要任何事件处理程序。

只需将 Dictionary 直接传递给 ListBox 的 ItemsSource 并将 DisplayMemberPathSelectedValuePath 设置为其 KeyValue 属性。因此,ListBox 会显示关键字符串,您可以通过 ListBox 的SelectedValue 属性直接访问 Graph 实例。

<StackPanel>
    <ListBox x:Name="listBox" DisplayMemberPath="Key" SelectedValuePath="Value"/>
    <TextBox Text="{Binding SelectedValue.Step, ElementName=listBox}"/>
</StackPanel>

所有的事情都可以自动使用后面的代码:

public MainWindow()
{
    InitializeComponent();

    listBox.ItemsSource = new Dictionary<string, Graph>()
    {
        { "Test_1", new Graph(10) },
        { "Test_2", new Graph(100) }
    };
}

【讨论】:

    猜你喜欢
    • 2014-03-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多