带有IEnumerable的WinRT DependencyProperty根本不触发 [英] WinRT DependencyProperty with IEnumerable not firing at all

查看:61
本文介绍了带有IEnumerable的WinRT DependencyProperty根本不触发的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在搜寻,因为我知道关于Dependency Properties的文章很多,但是我只是还没有看到有什么方法可以解决这个问题。我正在尝试将ViewModel的ObservableCollection绑定到AutoCompleteBox。我的ViewModel返回数据,Getter被击中。但是,此后,控件的SetValue或OnItemsSourcePropertyChanged不会触发。关于什么可能有什么问题的任何想法?



我有这样的控件:

  [ContentProperty(Name = ItemsSource)] 
公共部分类AutoCompleteBox:控件
{
//本地内容
private ListBox lb;
个人列表< Person> _items;
私人ObservableCollection< Person> _视图;

public AutoCompleteBox():base()
{
DefaultStyleKey = typeof(AutoCompleteBox);
已加载+ =(发送方,e)=> ApplyTemplate();
}
受保护的覆盖无效OnApplyTemplate()
{
this.lb = this.GetTemplateChild( Selector)as ListBox;
base.OnApplyTemplate();

}
#region ItemsSource

public IEnumerable ItemsSource
{
get {返回GetValue(ItemsSourceProperty)as ObservableCollection< Person> }
set {SetValue(ItemsSourceProperty,value); } //永远不会被调用
}

公共静态只读DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(
ItemsSource,
typeof(IEnumerable),
typeof(AutoCompleteBox),
个新的PropertyMetadata(null,OnItemsSourcePropertyChanged));

私有静态无效OnItemsSourcePropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
//永远不会被调用:(
}
#endregion

public String SearchText
{
get {返回GetValue(SearchTextProperty)as String;}
set
{
SetValue(SearchTextProperty,value);
}
}


公共静态只读DependencyProperty SearchTextProperty =
DependencyProperty.Register(
SearchText,
typeof(String) ,
typeof(AutoCompleteBox),
新的PropertyMetadata(null,OnSearchTextPropertyChanged));

私有静态无效OnSearchTextPropertyChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
//加载时触发,绑定数据
}

}

下面是e如何使用控件:

 < toolkit:AutoCompleteBox Grid.Row = 5 Grid.Column = 2 ItemsSource = {Binding Persons,Mode = TwoWay} SearchText = WhatTheHell /> 

作为测试,为了简单起见,我为SearchText创建了String DependencyProperty。如果我绑定SearchText,它会正常工作,则调用OnSearchTextPropertyChanged:

 < toolkit:AutoCompleteBox Grid.Row = 5 Grid.Column = 2 ItemsSource = {Binding Persons,Mode = TwoWay} SearchText = {Binding SearchText} /> 

还有其他人会遇到WinRT的这些问题吗?还是看到我的工作有什么问题?

解决方案

我会尝试检查是否使用DebugConverter触发了绑定-检查 BindingDebugConverter 。 / WinRTXamlToolkit rel = nofollow> WinRT XAML工具包-将其设置为绑定的转换器,并查看它是否以及何时断开(是在Convert还是ConvertBack中,设置了什么值,等等。)。 / p>

如果这样做没有帮助,请检查您的DataContext是否设置正确。



* EDIT 1



如果您要查找的是绑定集合中项目的更改-您可以检查ItemsSource是否为 INotifyCollectionChanged ,如果为true,请订阅 CollectionChanged 事件以查看更改。否则,您可以修改控件以继承 ItemsControl ,并覆盖 GetContainerForItemOverride IsItemItsOwnContainerOverride



* EDIT 2



里面有一个错误 Windows 8 Consumer Preview中与使用IEnumerable作为依赖项属性类型有关的框架。使用object作为类型可以解决问题。如果启用本机代码调试,则将看到此绑定异常:


错误:转换器无法转换类型为'System.Collections.ObjectModel的值.ObservableCollection`1 [[ACBDP.Person,ACBDP,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null]],System,Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089'键入'IEnumerable'; BindingExpression:Path = Persons DataItem = ACBDP.BlankPageViewModel,ACBDP,Version = 1.0.0.0,Culture = neutral,PublicKeyToken = null;目标元素是 ACBDP.AutoCompleteBox(名称=空);目标属性是 ItemsSource(类型为 IEnumerable)。



I've scoured and scoured since I know there has been a lot posted about Dependency Properties but I just haven't quite seen anything out there that has a solution that works. I'm trying to bind an ObservableCollection from my ViewModel to my AutoCompleteBox. My ViewModel is returning the data, the Getter is being hit. However, after that, the control's SetValue or OnItemsSourcePropertyChanged doesn't fire. Any thoughts as to what might be wrong?

I've got a control like so:

[ContentProperty(Name = "ItemsSource")]
public partial class AutoCompleteBox : Control
{
    //local stuff
    private ListBox lb;
    private List<Person> _items;
    private ObservableCollection<Person> _view;

    public AutoCompleteBox() : base()
    {
        DefaultStyleKey = typeof(AutoCompleteBox);
        Loaded += (sender, e) => ApplyTemplate();
    }
    protected override void OnApplyTemplate()
    {
        this.lb = this.GetTemplateChild("Selector") as ListBox;
        base.OnApplyTemplate();

    }
    #region ItemsSource

    public IEnumerable ItemsSource
    {
        get { return GetValue(ItemsSourceProperty) as ObservableCollection<Person>; }
        set { SetValue(ItemsSourceProperty, value); } //Never gets called
    }

    public static readonly DependencyProperty ItemsSourceProperty =
        DependencyProperty.Register(
            "ItemsSource",
            typeof(IEnumerable),
            typeof(AutoCompleteBox),
            new PropertyMetadata(null, OnItemsSourcePropertyChanged));

    private static void OnItemsSourcePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
       //Never gets called :(
    }
    #endregion

    public String SearchText
    {
        get { return GetValue(SearchTextProperty) as String; }
        set
        {
            SetValue(SearchTextProperty, value);
        }
    }


    public static readonly DependencyProperty SearchTextProperty =
        DependencyProperty.Register(
            "SearchText",
            typeof(String),
            typeof(AutoCompleteBox),
            new PropertyMetadata(null, OnSearchTextPropertyChanged));

    private static void OnSearchTextPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
         //gets fired when loaded, with data being bound
    }

}

Below is the how it is being used the control:

<toolkit:AutoCompleteBox Grid.Row="5" Grid.Column="2" ItemsSource="{Binding Persons,Mode=TwoWay}" SearchText="WhatTheHell"/>

As a test and for simplicity sake, I created a String DependencyProperty for SearchText. It works fine if I bind the SearchText, the OnSearchTextPropertyChanged is called:

<toolkit:AutoCompleteBox Grid.Row="5" Grid.Column="2" ItemsSource="{Binding Persons,Mode=TwoWay}" SearchText="{Binding SearchText}"/>

Anybody else experience these issues with WinRT? Or see anything wrong with what I am doing?

解决方案

I would try checking if the binding ever fires with a DebugConverter - check the BindingDebugConverter in the WinRT XAML Toolkit - set it as a converter for your binding and see if and when it breaks (is it in Convert or ConvertBack, what value is being set etc.).

If that does not help - check if your DataContext is set correctly.

*EDIT 1

If what you are looking is changes in the items of the bound collection - you can check if ItemsSource is an INotifyCollectionChanged and if true - subscribe to the CollectionChanged event to see the changes. Otherwise - you could modify your control to inherit from ItemsControl and override methods like GetContainerForItemOverride and IsItemItsOwnContainerOverride.

*EDIT 2

It seems like there is a bug in the framework in Windows 8 Consumer Preview related to using IEnumerable as the type of a dependency property. Using object as the type solves the problem. If you enable native code debugging you will see this binding exception:

Error: Converter failed to convert value of type 'System.Collections.ObjectModel.ObservableCollection`1[[ACBDP.Person, ACBDP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' to type 'IEnumerable'; BindingExpression: Path='Persons' DataItem='ACBDP.BlankPageViewModel, ACBDP, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'; target element is 'ACBDP.AutoCompleteBox' (Name='null'); target property is 'ItemsSource' (type 'IEnumerable').

这篇关于带有IEnumerable的WinRT DependencyProperty根本不触发的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆