将 ListBox SelectedItems 数据绑定到 ViewModel

Databinding ListBox SelectedItems to ViewModel

我正在尝试使用我创建的附加 属性 对 ListBox SelectedItems 属性进行数据绑定。我设置了一个名为 ListBoxFix 的 class,它位于名为 ControlFixes 的文件夹中。它的代码是一个非常简单的依赖关系 属性 如下所示:

using System.Windows;
using System.Windows.Controls;

namespace QMAC.ControlFixes
{
    public static class ListBoxFix
    {
        public static bool GetSelectedItemsBinding(ListBox element)
        {
            return (bool)element.GetValue(SelectedItemsBindingProperty);
        }

        public static void SetSelectedItemsBinding(ListBox element, bool value)
        {
            element.SetValue(SelectedItemsBindingProperty, value);
            if (value)
            {
                element.SelectionChanged += (sender, args) =>
                {
                    var x = element.SelectedItems;
                };
            }
        }

        public static readonly DependencyProperty SelectedItemsBindingProperty =
            DependencyProperty.RegisterAttached("FixSelectedItemsBinding",
            typeof(bool), typeof(FrameworkElement), new PropertyMetadata(false));
    }
}

在我的 XAML 代码中,我有以下标记:

<Window x:Class="QMAC.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:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
        xmlns:fix="clr-namespace:QMAC.ControlFixes"
        x:Name="Window"
        DataContext="{Binding Main, Mode=OneWay, Source={StaticResource Locator}}"
        Title="QMAC" Width="554.779" ResizeMode="CanMinimize" Height="539" Icon="logo.ico" >
    <Grid Background="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" RenderTransformOrigin="0.593,0.948" Margin="0,0,0,1">

        <ListBox x:Name="schoolListBox" HorizontalAlignment="Left" Margin="25,86,0,0" Width="274" FontSize="16" SelectionMode="Extended" ItemsSource="{Binding LocationList}" fix:ListBox.SelectedItemsBindingProperty="true"  VerticalAlignment="Top" Height="364"></ListBox>
    </Grid>
</Window>

不幸的是,我在设置标记时遇到了 3 个错误。他们是

Error   1   The name "ListBox" does not exist in the namespace "clr-namespace:QMAC.ControlFixes".
Error   2   The attachable property 'SelectedItemsBindingProperty' was not found in type 'ListBox'.
Error   3   The property 'ListBox.SelectedItemsBindingProperty' does not exist in XML namespace 'clr-namespace:QMAC.ControlFixes'.

我主要是想了解为什么它要在我的 ControlFixes 命名空间中寻找 ListBox?

您以错误的方式声明和使用了附加的 属性。我建议你仔细阅读 this well written overview.

您的代码中存在以下错误:

  • 您附加的 属性 的所有者类型被错误地指定为 FrameworkElement
  • 注册的 属性 名称与包含它的静态字段不匹配
  • 您尝试通过 ListBox class 使用附加的 属性 尽管您已经在 ListBoxFix class.[=41= 中定义了它]

正确的附加 属性 定义应与此类似:

public static class ListBoxFix
{
    public static bool GetSelectedItemsBinding(ListBox element)
    {
        return (bool)element.GetValue(SelectedItemsBindingProperty);
    }

    public static void SetSelectedItemsBinding(ListBox element, bool value)
    {
        element.SetValue(SelectedItemsBindingProperty, value);
    }

    public static readonly DependencyProperty SelectedItemsBindingProperty =
        DependencyProperty.RegisterAttached("SelectedItemsBinding",
        typeof(bool), typeof(ListBoxFix), new PropertyMetadata(false));
}

请注意,RegisterAttached() 方法的 ownerType 参数提供包含附加 属性 的 class 的类型。也看看 name 参数。

你的附件的正确用法属性:

<ListBox fix:ListBoxFix.SelectedItemsBinding="true"/>

更新:

您可能希望以 "WPF" 样式使用附加的 属性。那么最好将你的 class 设计成从 DependencyObject 派生。这是 MSDN 声明的内容:

If your class is defining the attached property strictly for use on other types, then the class does not have to derive from DependencyObject. But you do need to derive from DependencyObject if you follow the overall WPF model of having your attached property also be a dependency property.