【问题标题】:Multi-Select ListBox Binding Issue多选列表框绑定问题
【发布时间】:2014-09-24 12:43:39
【问题描述】:

我创建了一个从 ListBox 派生的自定义控件,但在将“SelectedItemsList”绑定到视图模型中的相应属性时遇到问题。

问题:列表框中的选定项没有进入它在视图模型中绑定的属性。列表框允许进行多项选择,但这些都不能进入视图模型中的列表。

多选列表框:

public class MultiSelectListBox : ListBox
{
    public MultiSelectListBox() { }

    public static readonly DependencyProperty SelectedItemsListProperty =
        DependencyProperty.Register(
            "SelectedItemsList", 
            typeof(IList), 
            typeof(MultiSelectListBox),
            new PropertyMetadata(default(IList)));
    public IList SelectedItemsList
    {
        get { return (IList) GetValue(SelectedItemsListProperty); }
        set { SetValue(SelectedItemsListProperty, value); }
    }
}

MainWindow.xaml 中的声明:

<local:MultiSelectListBox
    DataContext="{StaticResource viewModel}"
    DockPanel.Dock="Left"
    Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}"
    ItemsSource="{Binding SelectedOutputtapeList}"
    SelectionMode="Multiple"
    SelectedItemsList="{Binding SelectedOutputTapes, Mode=TwoWay}"
    HorizontalAlignment="Right"
    Background="DeepSkyBlue"
    Foreground="MidnightBlue"
    ScrollViewer.VerticalScrollBarVisibility="Visible"
    Height="100"
    Width="70"
    Margin="5"/>

查看模型(简化):

public class BTLogFrontEndViewModel : ViewModelBase
{
    private List<string> selectedOutputTapes;
    public BTLogFrontEndViewModel()
    {
        selectedOutputTapes = new List<string>();
    }
    public List<string> SelectedOutputTapes
    {
        get
        {
            return selectedOutputTapes;
        }
        set
        {
            selectedOutputTapes = value;
            OnPropertyChanged("SelectedOutputTapes");
        }
    }
}

【问题讨论】:

  • 发布 ObservableCollection 的代码,您是否在 Visual Studio 的输出窗口中看到任何绑定错误?
  • ObservableCollection 是一个 .NET 集合,没有可显示的代码。
  • 我的意思是 SelectedOutputTapes 的声明,而不是 ObservableCollection 的源代码。另外,I am having issues 是什么意思?你能对问题陈述更准确吗?
  • Rohit,我已经更详细地更新了我的问题。感谢您到目前为止的帮助,我很感激。

标签: c# wpf xaml listbox wpf-controls


【解决方案1】:

一种方法是不使用自定义 ListBox,而是使用列表中扩展 INotifyPropertyChanged 的​​对象:

<ListBox
    Width="70"
    Height="100"
    HorizontalAlignment="Right"
    Margin="5"
    Background="DeepSkyBlue"
    DockPanel.Dock="Left"
    Foreground="MidnightBlue"
    ItemsSource="{Binding SelectedOutputtapeList}"
    ScrollViewer.VerticalScrollBarVisibility="Visible"
    SelectionMode="Multiple"
    DisplayMemberPath="Description"
    Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="{x:Type ListBoxItem}">
            <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>

假设 BTLogFrontEndViewModel 是您的 DataContext:

public class BTLogFrontEndViewModel : ViewModelBase
{
    private ObservableCollection<OutputTapeViewModel> m_SelectedOutputtapeList;

    public ObservableCollection<OutputTapeViewModel> SelectedOutputtapeList
    {
        get
        {
            return m_SelectedOutputtapeList;
        }
        set
        {
           m_SelectedOutputtapeList = value;

           NotifyPropertyChanged("SelectedOutputtapeList");
        }
    }
}

OutputTapeViewModel 声明如下:

public class OutputTapeViewModel : ViewModelBase
{
    private string m_Description;

    public string Description
    {
        get
        {
            return m_Description;
        }
        set
        {
            m_Description = value;

            NotifyPropertyChanged("Description");
        }
    }

    private bool m_IsSelected;

    public string IsSelected
    {
        get
        {
            return m_IsSelected;
        }
        set
        {
            m_IsSelected = value;

            NotifyPropertyChanged("IsSelected");
        }
    }
}

需要注意的重要事项是在列表框上我添加了 DisplayMemberPath 属性,以便使用 OutputTapeViewModel 类中的描述字段来显示列表框上的内容。它还具有项容器样式,当在 ListBox 中选择时,它绑定到 OutputTapeViewModel.IsSelected 属性。此 OutputTapeViewModel.IsSelected 允许您通过以下方式使用 BTLogFrontEndViewModel.SelectedOutputtapeList 属性:

var selectedItems = SelectedOutputtapeList.Where(item => item.IsSelected);

这仅适用于您不关心执行 LINQ 表达式的开销的情况。

【讨论】:

    猜你喜欢
    • 2011-11-05
    • 1970-01-01
    • 2015-08-02
    • 1970-01-01
    • 2012-03-01
    • 2012-05-10
    • 2010-11-22
    • 1970-01-01
    相关资源
    最近更新 更多