简体   繁体   中英

Databinding ListBox SelectedItems to ViewModel

I'm attempting to databind the ListBox SelectedItems attribute using an attached property I've created. I set up a class called ListBoxFix which is located in a folder called ControlFixes. It's code is a very simple dependency property shown below:

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

In my XAML code I have the following markup:

<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>

Unfortunately, I'm getting the 3 errors to how I've setup my markup. They are

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'.

I'm mainly trying to understand why it's looking for ListBox in my ControlFixes namespace?

You declare and use the attached property in a wrong way. I would suggest you to read carefully this well written overview .

There are following mistakes in your code:

  • The owner type for your attached property is incorrectly specified as FrameworkElement .
  • The registered property name does not match the static field containing it
  • You try to use your attached property via the ListBox class although you have defined it in your ListBoxFix class.

The proper attached property definition should look similar to this:

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

Note that the ownerType parameter of the RegisterAttached() method provides the type of your class containing the attached property. Take a look on the name parameter too.

The proper usage of your attached property:

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

Update:

You might want to use your attached property in a "WPF" style. Then it would be better to design your class to be derived from DependencyObject . This is what MSDN states:

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM