C# 将附加属性绑定到视图模型失败
我为ListBox创建了一个附加属性,如下所示:C# 将附加属性绑定到视图模型失败,c#,.net,wpf,data-binding,attached-properties,C#,.net,Wpf,Data Binding,Attached Properties,我为ListBox创建了一个附加属性,如下所示: using ListBoxControl = System.Windows.Controls.ListBox; namespace App.Ui.Views.AttachedProperties { public class ListBox { public static readonly DependencyProperty autoScrollProperty = Dependency
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);
}
}
}
当我在xaml中使用静态真/假值时,它可以正常工作:
<ListBox ap:ListBox.AutoScroll="True">
...
</ListBox>
...
但如果我将数据绑定到视图模型中的属性:
<ListBox ap:ListBox.AutoScroll="{Binding Path=Settings.EnableAutoScroll}">
...
</ListBox>
...
然后我得到了以下异常:无法在“ListBox”类型的“SetAutoScroll”属性上设置“Binding”。“绑定”只能在DependencyObject的DependencyProperty上设置。
这是可能的,还是我需要派生自己的自定义列表框来实现这一点?这一行的问题
typeof(ListBoxControl)
。您应该指定自定义附加属性所在的类的名称
我建议将类从ListBox重命名为ListBoxExtensions,并使其成为静态的。这样就不必使用alias ListBoxControl您的最终代码如下所示:
public static class ListBoxExtensions
{
public static readonly DependencyProperty autoScrollProperty =
DependencyProperty.RegisterAttached(
"AutoScroll",
typeof(bool),
typeof(ListBoxExtensions),
new PropertyMetadata(false));
...
}
编辑:
好的,您的代码还有一个问题从setter(
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
的别名。请参阅using语句。我的印象是,第二个类型参数是您附加到的依赖项对象的类型。键入注释时,您的编辑没有刷新。我来试一试。进行您建议的更改会使代码停止使用静态值。我很确定第二个类型参数是您将属性附加到的依赖对象的类型。自定义附加属性的要点是它们可以附加到任何元素。这使它们非常灵活。我更新了答案。应该有帮助。