Data binding attached property to view model fails

The name of the pictureThe name of the pictureThe name of the pictureClash 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 is an alias for System.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


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.

Popular posts from this blog

Firebase Auth - with Email and Password - Check user already registered

Dynamically update html content plain JS

How to determine optimal route across keyboard