2

WindowsPhone7でSilverlightを使用しています。

VirtualizingStackPanelを使用しているときに、「BindingExpressionパスエラー」デバッグメッセージが大量に表示されるのは正常ですか?ビジュアルアイテムはリサイクルされるため、データアイテムコレクションから一時的にバインドされていないために発生していると思います...

ItemsPanelのItemsPanelTemplateがVirtualizingStackPanelであるItemsControlがあります。これは、ViewModelの「Notes」ObservableCollectionにバインドされます。

<ItemsControl x:Name="ListView" ItemsSource="{Binding Notes}" 
              ItemTemplate="{StaticResource ListDataTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <VirtualizingStackPanel/>
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
    <ItemsControl.Template>
        <ControlTemplate>
            <ScrollViewer x:Name="ScrollViewer" Padding="{TemplateBinding Padding}">
                <ItemsPresenter/>
            </ScrollViewer>
        </ControlTemplate>
    </ItemsControl.Template>
</ItemsControl>

これは、DataContextがMainViewModelViewModelに設定されているUserControl内にあります。

ListDataTemplateには、NotesObservableCollection内のアイテムのプロパティにデータバインドされたテキストを含むボタンが含まれています。

<DataTemplate x:Key="ListDataTemplate">
        <Button>
        <Grid>
            <TextBlock TextWrapping="Wrap" Text="{Binding Title}">
        </Grid>
    </Button>
</DataTemplate>

プログラムを実行すると、すべて正常に機能します。Notesコレクション内の少数のアイテムのみが一度にバインドされます。ただし、上下にスクロールすると、多くのデバッグエラーが発生します。

System.Windows.Data Error: BindingExpression path error: 'Title' property not found on 'EnWp7.ViewModels.MainViewModel' 'EnWp7.ViewModels.MainViewModel' (HashCode=119211466). BindingExpression: Path='Title' DataItem='EnWp7.ViewModels.MainViewModel' (HashCode=119211466); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
System.Windows.Data Error: BindingExpression path error: 'Title' property not found on 'EnWp7.ViewModels.MainViewModel' 'EnWp7.ViewModels.MainViewModel' (HashCode=119211466). BindingExpression: Path='Title' DataItem='EnWp7.ViewModels.MainViewModel' (HashCode=119211466); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
System.Windows.Data Error: BindingExpression path error: 'Title' property not found on 'EnWp7.ViewModels.MainViewModel' 'EnWp7.ViewModels.MainViewModel' (HashCode=119211466). BindingExpression: Path='Title' DataItem='EnWp7.ViewModels.MainViewModel' (HashCode=119211466); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..
System.Windows.Data Error: BindingExpression path error: 'Title' property not found on 'EnWp7.ViewModels.MainViewModel' 'EnWp7.ViewModels.MainViewModel' (HashCode=119211466). BindingExpression: Path='Title' DataItem='EnWp7.ViewModels.MainViewModel' (HashCode=119211466); target element is 'System.Windows.Controls.TextBlock' (Name=''); target property is 'Text' (type 'System.String')..

メインビューモデル(NotesプロパティはItemsSource)で "Title"プロパティを探しています-これは正常だと思います-ビジュアルアイテムがNotesコレクション内のアイテムからバインドされていないため、一時的な状況です。コレクション内の別のアイテムに割り当てることでリサイクルされます。

他の誰かがこれを見たことがありますか?私はそれが正常であるということは正しいですか?

MainViewModelにダミーのTitleプロパティを作成し、デバッグブレークポイントを設定すると、このスタックトレースが表示されます。「UnlinkContainerFromItem」に注意してください。

...!EnWp7.ViewModels.MainViewModel.Title.get() Line 54  C#
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(System.Reflection.RuntimeMethodInfo rtmi = {System.Reflection.RuntimeMethodInfo}, object obj = {EnWp7.ViewModels.MainViewModel}, System.Reflection.BindingFlags invokeAttr = Default, System.Reflection.Binder binder = null, object parameters = null, System.Globalization.CultureInfo culture = null, bool isBinderDefault = false, System.Reflection.Assembly caller = null, bool verifyAccess = true, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller) 
mscorlib.dll!System.Reflection.RuntimeMethodInfo.InternalInvoke(object obj = {EnWp7.ViewModels.MainViewModel}, System.Reflection.BindingFlags invokeAttr = Default, System.Reflection.Binder binder = null, object[] parameters = null, System.Globalization.CultureInfo culture = null, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller) + 0x14e bytes 
mscorlib.dll!System.Reflection.RuntimePropertyInfo.InternalGetValue(System.Reflection.PropertyInfo thisProperty = {System.Reflection.RuntimePropertyInfo}, object obj = {EnWp7.ViewModels.MainViewModel}, object[] index = null, ref System.Threading.StackCrawlMark stackMark = LookForMyCaller) + 0x4e bytes  
mscorlib.dll!System.Reflection.RuntimePropertyInfo.GetValue(object obj = {EnWp7.ViewModels.MainViewModel}, object[] index = null) + 0x2 bytes   
System.Windows.dll!System.Windows.CLRPropertyListener.Value.get() + 0x1b bytes  
System.Windows.dll!System.Windows.PropertyAccessPathStep.ConnectToPropertyInSource() + 0x148 bytes  
System.Windows.dll!System.Windows.PropertyAccessPathStep.ConnectToProperty() + 0x16 bytes   
System.Windows.dll!System.Windows.PropertyAccessPathStep.ReConnect(object newSource = {EnWp7.ViewModels.MainViewModel}) + 0x13 bytes    
System.Windows.dll!System.Windows.PropertyPathListener.ReConnect(object source = {EnWp7.ViewModels.MainViewModel}) + 0x10 bytes 
System.Windows.dll!System.Windows.Data.BindingExpression.SourceAquired() + 0x11 bytes   
System.Windows.dll!System.Windows.Data.BindingExpression.DataContextChanged(object o = {System.Windows.Controls.TextBlock}, System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x26 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x15 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x11 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnAncestorDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x18 bytes   
System.Windows.dll!System.Windows.FrameworkElement.NotifyDataContextChanged(System.Windows.DataContextChangedEventArgs e = {System.Windows.DataContextChangedEventArgs}) + 0x59 bytes   
System.Windows.dll!System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyProperty dp = {System.Windows.CoreDependencyProperty}) + 0x1d bytes   
System.Windows.dll!System.Windows.DependencyObject.RaisePropertyChangeNotifications(System.Windows.DependencyProperty dp = {System.Windows.CoreDependencyProperty}, object newValue = {EnWp7.ViewModels.MainViewModel}, object oldValue = {EnWp7.Store.NoteLocal}) + 0x38 bytes 
System.Windows.dll!System.Windows.DependencyObject.ClearValueInternal(System.Windows.DependencyProperty dp = {System.Windows.CoreDependencyProperty}) + 0x138 bytes 
System.Windows.dll!System.Windows.DependencyObject.ClearValue(System.Windows.DependencyProperty dp = {System.Windows.CoreDependencyProperty}) + 0x7 bytes   
System.Windows.dll!System.Windows.Controls.ItemContainerGenerator.UnlinkContainerFromItem(System.Windows.DependencyObject container = {System.Windows.Controls.ContentPresenter}, object item = {EnWp7.Store.NoteLocal}, bool isRecycling = true) + 0x1f bytes  
System.Windows.dll!System.Windows.Controls.ItemContainerGenerator.Remove(System.Windows.Controls.Primitives.GeneratorPosition position = {System.Windows.Controls.Primitives.GeneratorPosition}, int count = 2, bool isRecycling = true) + 0x14a bytes  
System.Windows.dll!System.Windows.Controls.ItemContainerGenerator.System.Windows.Controls.Primitives.IRecyclingItemContainerGenerator.Recycle(System.Windows.Controls.Primitives.GeneratorPosition position = {System.Windows.Controls.Primitives.GeneratorPosition}, int count = 2) + 0x9 bytes    
System.Windows.dll!System.Windows.Controls.VirtualizingStackPanel.CleanupRange(int startIndex = 0, int count = 2) + 0x20 bytes  
System.Windows.dll!System.Windows.Controls.VirtualizingStackPanel.CleanupContainers(System.Windows.Controls.ItemsControl itemsControl = {System.Windows.Controls.ItemsControl}) + 0x73 bytes    
System.Windows.dll!System.Windows.Controls.VirtualizingStackPanel.MeasureOverride(System.Windows.Size constraint = {System.Windows.Size}) + 0xe4 bytes  
System.Windows.dll!System.Windows.FrameworkElement.MeasureOverride(System.IntPtr nativeTarget = 102509504, float inWidth = 480.0, float inHeight = 499.0, out float outWidth = 0.0, out float outHeight = 0.0) + 0x45 bytes 

ありがとう、ダミアン

4

2 に答える 2

2

あなたの状況の評価は正しいと思いますが、それは動作のバグのように聞こえVirtualizingStackPanelます。必要な時点でのアプリケーションの実行やバインディングには影響しませんが、例外の発生は比較的コストのかかる操作であるためDataContext、コンテナーのリンクを解除するときに適切なものを適宜更新することは理にかなっています。

潜在的なバグとしてそれを提起するのに最適な場所は、 AppHubフォーラムにあると思います

于 2011-02-10T08:38:19.067 に答える
1

この投稿がかなり古いことは承知していますが、ダミー プロパティを作成せずに解決するには、項目の DataContext が期待どおりの型だけになるようにします。

これは、データ テンプレートのルートにある次のコンバーターで行います。

public class SpecificTypeConverter : IValueConverter
{
    public string Type { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType().FullName == this.Type)
        {
            return value;
        }

        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

次のように静的リソースを追加します。

<p:PhoneApplicationPage.Resources>
    <converters:SpecificTypeConverter x:Key="MustBeItem" Type="My.Namespace.MyListItemViewModel" /> 
</p:PhoneApplicationPage.Resources>

データ テンプレートでは、コンバーターを使用します。

<DataTemplate>
    <StackPanel DataContext="{Binding Converter={StaticResource MustBeItem}}" >
        <TextBlock Tekst="{Binding Path=Name}" />
    </StackPanel>
</DataTemplate>

現在、親の Name プロパティはチェックされません。

于 2013-05-28T14:47:16.933 に答える