【问题标题】:Binding from one ListBox to another ListBox?从一个 ListBox 绑定到另一个 ListBox?
【发布时间】:2016-06-03 07:14:44
【问题描述】:

我正在尝试将ListBox 绑定到同一窗口中的另一个ListBox。左侧Listbox 包含可供选择的数据。但我希望用户能够单击左侧列表框中的项目,并且这些相同的项目将显示在右侧的另一个列表框中。

【问题讨论】:

  • 您只想在另一个 ListBox 中显示相同的项目,而不是所选项目上存在的集合?如果您选择不同的项目,应该删除另一个列表框中的项目还是保留在列表框中?让我们看看你到目前为止有什么并弄清楚。
  • 给出一些代码来了解你是如何填充第一个 ListBox 的。所选项目的选择会随着在其中添加值的方式而改变。

标签: c# wpf xaml data-binding listbox


【解决方案1】:

已编辑:当然,您可以使用 ElementName 将 UI 属性绑定到另一个 UI 属性(实际上是 Dependency Property),但我建议将属性绑定到一个视图模型。请参阅下面的简化示例。

查看模型:

public ObservableCollection<ItemObject> Items  { get; set; }
public ObservableCollection<ItemObject> SelectedItems { get; set; }

左:

<ListBox ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}" />

(请注意实际上没有 SelectedItems 依赖属性。请参阅类似问题:Select multiple items from a DataGrid in an MVVM WPF project

对:

<ListBox ItemsSource="{Binding SelectedItems}" />

这很好用。此外,通过这种方法,可以轻松自定义右侧的列表(例如,使用CollectionView 进行排序、过滤……)。

private ICollectionView _collectionView;
private ICollectionView _CollectionView {
    get { return _collectionView
        ?? (_collectionView = CollectionViewSource.GetDefaultView(SelectedItems)); }
}
public ICollectionView FilteredItems { 
    get { _CollecitionView.Filter(...); }
}

<ListBox ItemsSource={"Binding FilteredSelectedItems"} />

这种 MVVM 方法有时很费力,但最终发现是有益的。

【讨论】:

  • 将一个 UI 项绑定到另一个到底有什么问题?
  • 我猜想绑定到 VM 可以提高应用程序设计的灵活性 - 例如显示用户选择的最后两项如何?但是问题是如何绑定到另一个 UI 属性,它本身并没有错。只是建议一种替代方法。
  • 您关于显示最后两个项目的问题不清楚,是针对我还是一般?我的示例显示了根据用户请求在列表框中选择的所有项目。 TextBlock 仅显示 SelectedItem 字段中报告的内容,根据设计,该字段仅包含一项。如果需要在TextBlock 中显示更多项目,则需要将其绑定到SelectedItems,并且需要编写一个转换器以从数据列表中返回一个字符串。但是 OP 并没有要求...我只是展示它来提供对差异的理解。
  • 请理解我不是在挑战你……我也不是指TextBlock 显示“这两个项目”。只是建议,例如,使用 VM,可以轻松过滤 SelectedItems
  • 我明白了。 :-) 我想做的就是让你的答案更好,以免留下开放式的陈述;对你来说显而易见的事情可能对其他人来说并不明显。只需用这些想法更新您的答案以帮助用户。
【解决方案2】:

您命名第一个列表框,然后 xaml 上的任何其他控件都将使用绑定的 ElementName 属性中的名称绑定到该控件。

例如,有两个列表框和一个文本框。顶部列表框具有多项选择,并且这些选择显示在下部列表框中。而文本框只选择第一个项目。

<StackPanel Orientation="Vertical">
    <StackPanel.Resources>
        <converters:PathToFilenameConverter x:Key="FilenameConverter" />
        <x:Array x:Key="FileNames" Type="system:String">
            <system:String>C:\Temp\Alpha.txt</system:String>
            <system:String>C:\Temp\Beta.txt</system:String>
            <system:String>C:\Temp\Gamma.txt</system:String>
        </x:Array>
    </StackPanel.Resources>

    <ListBox  Name="lbFiles"
              SelectionMode="Multiple"
              ItemsSource="{StaticResource FileNames}"
              Margin="10"/>

    <ListBox ItemsSource="{Binding SelectedItems, ElementName=lbFiles }"  Margin="10" />

    <TextBlock Text="{Binding SelectedItem, 
                      ElementName=lbFiles,
                      Converter={StaticResource FilenameConverter}}"
               Margin="10" />

</StackPanel>

注意...代码是使用下方列表框的SelectedItems 属性绑定的,而不是TextBlock 使用的SelectedItem


顺便说一句,另一个答案使用ObservableCollection,除非数组动态变化,否则不需要这样做;否则可以使用任何数组。根据加载,例如从 VM 加载,它可能需要遵守 INotifyPropertyChanged

【讨论】:

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