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