【问题标题】:Binding RightListBox and TextBox绑定 RightListBox 和 TextBox
【发布时间】:2019-11-16 16:18:45
【问题描述】:

已编辑:

我在代码中加入了两个不同的程序:

  1. 两个 ListBox(LeftListBoxRightListBox),用于在两者之间传输项目
  2. 一个ListBox(称为listBox_Selector)和一个TextBox,用于显示与listBox_Selector中的SelectedItem对应的数字

现在我想合并这两个并将listBox_Selector 替换为RightListBox

我的目标:选择了RightListBox(不是@ 987654331)的项目,相应的数字应该显示(例如,如果键=“test_2”,则值= 20等)。然后,我想删除listBox_Selector。 但是,我不能。这很困难,因为RightListBox 使用TestModel,而listBox_Selector 使用Dictionary<string, Graph>

这是我的代码:

MainWindow.xaml.cs

using ListBoxMoveAll.Model;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;

namespace ListBoxMoveAll
{
    public partial class MainWindow : Window
    {
        public ObservableCollection<TestModel> LeftListBoxItems { get; } = new ObservableCollection<TestModel>();
        public ObservableCollection<TestModel> RightListBoxItems { get; } = new ObservableCollection<TestModel>();

        public MainWindow()
        {
            InitializeComponent();
            DataContext = this;
            LeftListBoxItems.Add(new TestModel("Test_1"));
            LeftListBoxItems.Add(new TestModel("Test_2"));
            LeftListBoxItems.Add(new TestModel("Test_3"));

            listBox_Selector.ItemsSource = new Dictionary<string, Graph>()
            // RightListBox.ItemsSource = new Dictionary<string, Graph>()
            {
                { "Test_1", new Graph(10) },
                { "Test_2", new Graph(20) },
                { "Test_3", new Graph(30) }
            };
        }

        private void Add_Button_Click(object sender, RoutedEventArgs e)
        {
            foreach (TestModel item in LeftListBox.SelectedItems.OfType<TestModel>().ToList())
            {
                LeftListBoxItems.Remove(item);
                RightListBoxItems.Add(item);
            }
        }

        private void Remove_Button_Click(object sender, RoutedEventArgs e)
        {
            foreach (TestModel item in RightListBox.SelectedItems.OfType<TestModel>().ToList())
            {
                RightListBoxItems.Remove(item);
                LeftListBoxItems.Add(item);
            }
        }
    }
}

MainWindow.xaml

<Window x:Class="ListBoxMoveAll.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:ListBoxMoveAll"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="647.096">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="80" />
            <ColumnDefinition Width="2*" />
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <ListBox x:Name="LeftListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="0"
            DisplayMemberPath="TestItem" ItemsSource="{Binding LeftListBoxItems}"
            SelectionMode="Extended" Margin="0,10"/>
        <StackPanel Grid.Column="1" Grid.Row="0" VerticalAlignment="Center">
            <Button Content="Add" x:Name="Add_Button" Click="Add_Button_Click"/>
        </StackPanel>
        <StackPanel Grid.Column="1" Grid.Row="2" VerticalAlignment="Center">
            <Button Content="Remove" x:Name="Remove_Button" Click="Remove_Button_Click"/>
        </StackPanel>
        <ListBox x:Name="RightListBox" Grid.Row="0" Grid.RowSpan="3" Grid.Column="2"
            DisplayMemberPath="TestItem" ItemsSource="{Binding RightListBoxItems}"
            SelectionMode="Extended" Margin="0,10"/>

        <StackPanel Grid.Column="4" Grid.Row="0" Grid.RowSpan="1" Margin="0,10">
            <ListBox x:Name="listBox_Selector" DisplayMemberPath="Key" SelectedValuePath="Value"/>
        </StackPanel>
        <StackPanel Grid.Column="4" Grid.Row="1" Grid.RowSpan="1" Margin="0,10">
            <TextBox Text="{Binding SelectedValue.Step, ElementName=listBox_Selector}"/>
        </StackPanel>
    </Grid>
</Window>

模型/TestItem.cs

namespace ListBoxMoveAll.Model
{
    public class TestModel
    {
        public TestModel(string _testItem)
        { TestItem = _testItem; }

        public string TestItem { get; set; }
    }
}

模型/Graph.cs

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

        public int Step { get; set; }
    }
}

我尝试更改为RightListBox.ItemsSource = new Dictionary&lt;string, Graph&gt;(),但卡住了。请帮我。提前谢谢你。

【问题讨论】:

  • 不清楚您要实现什么,您的列表框选择器有一个 Graph 对象的项目源,而您的右侧列表框有一个 TestModel 集合作为项目源,它没有绑定到文本框的属性!
  • @SamTheDev 对不起,我的解释很糟糕。我想用RightListBox 替换listBox_Selector。选择RightListBox的项目时,应显示相应的数字(如果键=“test_2”,则值= 20等)。您应该将TestModelstring 进行比较,如Dictionary&lt;string, Graph()&gt;。它们都是输入,而Graph 是输出。请运行我的代码并单击listBox_Selector 中的Test_2。应该显示20。我希望RightListBox 上的行为相同(然后删除listBox_Selector)。
  • 大家好,我刚刚解决了一些问题,所以我创建了另一个问题here。如果可以,请查看我想要实现的目标并回答我的问题。关闭这个问题我没有任何问题,所以我可能会删除它。谢谢你们。

标签: c# wpf dictionary binding listbox


【解决方案1】:

这就是我们使用价值转换器的地方。

public class GraphValueConverter:IValueConverter  
    {  
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
        {  
            var graph = value as Graph;
            // check for null
            return graph.Step;  
        }  
        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)  
        {  
            throw new NotImplementedException();  
        }  
    }  

然后在您的 XAML 导入值转换器中:

<Window.Resources>  
        <local:GraphValueConverter x:Key="valueconverter"></local:GraphValueConverter>   
    </Window.Resources> 

使用导入的值转换器:

<TextBox Text="{Binding SelectedValue.Step, ElementName=listBox_Selector,Converter={StaticResource valueconverter}}"/>

检查定义了值转换器的命名空间。如果它在您的示例中位于不同的命名空间中,例如“ListBoxMoveAll.Model”。您也应该在您的 xaml 中导入该命名空间:

<Window x:Class="ListBoxMoveAll.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:ListBoxMoveAll"
        xmlns:model="clr-namespace:ListBoxMoveAll.Model" <--  add this
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="647.096">

然后将您的导入更改为:

<Window.Resources>
 <model:GraphValueConverter x:Key="valueconverter"></model:GraphValueConverter>   
</Window.Resources> 

【讨论】:

  • 谢谢,但我得到了一个错误MC3074: The tag 'GraphValueConverter' does not exist in XML namespace 'clr-namespace:ListBoxMoveAll'. 不管怎样,它并没有消失(我删除了Debug下的所有文件,然后是Clean Solution,Rebuild Solution等)。您是否也尝试在您的机器上编译您的代码?也许不是,因为我害怕,但是你的TextBox 有一个额外的}"。无论如何,你知道如何解决这个问题吗?
  • 我没有测试我的代码。我试图指导您如何添加和使用值转换器。这似乎是一个命名空间问题,我将为此编辑我的答案。
  • 谢谢,但仍然不起作用,即使我用model: 替换了 。与 local: 的行为相同。现在local: 是灰色的,model: 是正常颜色,所以路径必须是正确的。它对你有用吗?
猜你喜欢
  • 2011-04-23
  • 1970-01-01
  • 1970-01-01
  • 2011-05-20
  • 2011-01-28
  • 2010-12-09
  • 1970-01-01
  • 1970-01-01
  • 2015-08-21
相关资源
最近更新 更多