Data binding attached property to view model fails
Clash Royale CLAN TAG#URR8PPP
Data binding attached property to view model fails
I created an attached property for ListBox like this:
using ListBoxControl = System.Windows.Controls.ListBox;
namespace App.Ui.Views.AttachedProperties
public class ListBox
public static readonly DependencyProperty autoScrollProperty =
DependencyProperty.RegisterAttached(
"AutoScroll",
typeof(bool),
typeof(ListBoxControl),
new PropertyMetadata(false));
public static void SetAutoScroll(ListBoxControl element, bool value)
element.SetValue(autoScrollProperty, value);
if (value)
element.SelectionChanged += Element_SelectionChanged;
else
element.SelectionChanged -= Element_SelectionChanged;
public static bool GetAutoScroll(ListBoxControl element)
return (bool)element.GetValue(autoScrollProperty);
private static void Element_SelectionChanged(object sender, SelectionChangedEventArgs e)
var listBox = (ListBoxControl)sender;
listBox.ScrollIntoView(listBox.SelectedItem);
When I use a static True/False value in the xaml, it works fine:
<ListBox ap:ListBox.AutoScroll="True">
...
</ListBox>
But if I data bind to a property in my view model:
<ListBox ap:ListBox.AutoScroll="Binding Path=Settings.EnableAutoScroll">
...
</ListBox>
Then I get the following exception: A 'Binding' cannot be set on the 'SetAutoScroll' property of type 'ListBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
A 'Binding' cannot be set on the 'SetAutoScroll' property of type 'ListBox'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject.
Is this possible, or am I going to need to derive my own custom list box to accomplish this?
1 Answer
1
Problem in this line typeof(ListBoxControl)
. You should specify the name of the class where custom attached property seats.
typeof(ListBoxControl)
I would recommend rename class from ListBox to ListBoxExtensions, also, make it static. Then you don't have to use alias ListBoxControl.
Your final code will look like:
public static class ListBoxExtensions
public static readonly DependencyProperty autoScrollProperty =
DependencyProperty.RegisterAttached(
"AutoScroll",
typeof(bool),
typeof(ListBoxExtensions),
new PropertyMetadata(false));
...
Edit:
OK, your code has another problem.
Remove attachment of the listener from setter (SetAutoScroll
) and put this logic into dependency property callback.
SetAutoScroll
public static class ListBoxExtensions
public static readonly DependencyProperty autoScrollProperty =
DependencyProperty.RegisterAttached(
"AutoScroll",
typeof(bool),
typeof(ListBoxExtensions),
new PropertyMetadata(false, AutoScrollChangedCallback));
public static void SetAutoScroll(ListBox element, bool value)
element.SetValue(autoScrollProperty, value);
public static bool GetAutoScroll(ListBox element)
return (bool)element.GetValue(autoScrollProperty);
private static void AutoScrollChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
ListBox control = (ListBox)d;
if ((bool)e.NewValue)
control.SelectionChanged += Element_SelectionChanged;
else
control.SelectionChanged -= Element_SelectionChanged;
private static void Element_SelectionChanged(object sender, SelectionChangedEventArgs e)
var listBox = (ListBox)sender;
listBox.ScrollIntoView(listBox.SelectedItem);
ListBoxControl
System.Windows.Controls.Listbox
Your edit didn't refresh when typed the comment. I'll give this a shot.
– Jesse
Aug 12 at 3:09
Making the changes that you have suggested makes the code stop functioning with static values. I'm pretty sure that that second type parameter is the type of the dependency object which you are attaching the property to.
– Jesse
Aug 12 at 3:15
Point of custom attached properties is that they can be attached to any element. This makes them very flexible. I updated answer. Should help.
– lezhkin11
Aug 12 at 3:44
That works perfect. Thank you.
– Jesse
Aug 12 at 4:01
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
ListBoxControl
is an alias forSystem.Windows.Controls.Listbox
. See the using statement. I was under the impression that the second type parameter was the type of the dependency object which you were attaching to.– Jesse
Aug 12 at 3:07