-1

My TextBox shows a property value of a class, which is changed based on the SelectedItem in ListBox. (So far, so good.) However, now I'd like to replace the value defined in Dictionary with a value which a user specified (The key is the SelectedItem in ListBox). This doesn't work, no matter what I do. It just throws an exception. Here is my full code:

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

... I think I just need one more step, but I cannot find the way. Please help me. Thank you in advance.

5
  • 2
    As a note, it is pointless to use ObservableCollection for the type of the oc and graph variables. There is nothing that would observe a collection change. They could be simple arrays. Commented Nov 12, 2019 at 15:13
  • @Clemens: I see, thank you. Maybe, next time I will make them List<>, instead of ObservableCollection<>. (It should be OK, right?) Commented Nov 12, 2019 at 15:18
  • 1
    And of course (sender as Graph) is always null, because sender is a TextBox. Commented Nov 12, 2019 at 15:30
  • @Clemens Oops, I didn't know that ... then, how can I get the user input in TextBox using sender (or any other way)? Commented Nov 12, 2019 at 15:49
  • @Clemens Oh, it makes sense, thank you. Let me correct one thing: I should have added lB = sender as ListBox; in listBox_SelectionChanged(). And, according to your suggestion, I should put this way: if (lB.SelectedItem != null) { if (dic.ContainsKey(lB.SelectedItem.ToString())) { dic[lB.SelectedItem.ToString()].Step = Convert.ToInt32(((TextBox)sender).Text); } }. However, it still give me an exception ... Is there any way to solve this? Commented Nov 12, 2019 at 17:28

1 Answer 1

1

Your approach is far too complicated. Actually, you do not need any event handlers at all.

Simply pass the Dictionary directly to the ListBox's ItemsSource and set DisplayMemberPath and SelectedValuePath to its Key and Value properties. Thus the ListBox displays the key strings and you can directly access a Graph instance via the SelectedValue property of the ListBox.

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

and everything works automatically with this code behind:

public MainWindow() { InitializeComponent(); listBox.ItemsSource = new Dictionary<string, Graph>() { { "Test_1", new Graph(10) }, { "Test_2", new Graph(100) } }; } 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.