DataContext of Window не может быть найден для DataTemplate - PullRequest
1 голос
/ 10 октября 2019

Я просмотрел несколько статей, но ни одна из них, похоже, не решает мою проблему.

Я пытаюсь связать видимость элемента управления Индикатор ожидания. Моя первая попытка была такой:

<dx:LoadingDecorator Panel.ZIndex="5"
                     DataContext="{Binding}"
                     SplashScreenDataContext="{Binding}">
    <dx:LoadingDecorator.SplashScreenTemplate>
        <DataTemplate >
            <dx:WaitIndicator DeferedVisibility="{Binding IsActive}" 
                      Content="Loading" />
        </DataTemplate>
    </dx:LoadingDecorator.SplashScreenTemplate>

    <!-- TreeList... -->

</dx:LoadingDecorator>

Это не сработало, согласно журналу, он не может найти значение, потому что DataItem имеет значение null.

Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:IsActive; DataItem=null; target element is 'WaitIndicator' (Name=''); target property is 'DeferedVisibility' (type 'Boolean')

(Забавный факт,если я выберу F12 после выбора IsActive, Visual Studio перейдет к правильному свойству в правильной модели представления)

После этого я попытался ссылаться на DataContext напрямую, как это

<dx:LoadingDecorator Panel.ZIndex="5"
                     DataContext="{Binding}"
                     SplashScreenDataContext="{Binding}">
    <dx:LoadingDecorator.SplashScreenTemplate>
        <DataTemplate >
            <dx:WaitIndicator DeferedVisibility="{Binding ElementName=ParentWindow, Path=DataContext.IsActive, diag:PresentationTraceSources.TraceLevel=High}" 
                      Content="Loading" />
        </DataTemplate>
    </dx:LoadingDecorator.SplashScreenTemplate>

    <!-- TreeList... -->

</dx:LoadingDecorator>

Где ParentWindow определяется так

<DXWindow x:Name="ParentWindow" />

и DataContext как обычно

<dx:DXWindow.DataContext>
    <vm:MainWindowViewModel />
</dx:DXWindow.DataContext>

Это тоже не работает, журнал показывает это

Created BindingExpression (hash=23511423) for Binding (hash=8575450)
  Path: 'DataContext.IsActive'
BindingExpression (hash=23511423): Default mode resolved to OneWay
BindingExpression (hash=23511423): Default update trigger resolved to PropertyChanged
BindingExpression (hash=23511423): Attach to DevExpress.Xpf.Core.WaitIndicator.DeferedVisibility (hash=24910686)
BindingExpression (hash=23511423): Resolving source 
BindingExpression (hash=23511423): Found data context element: <null> (OK)
    Lookup name ParentWindow:  queried WaitIndicator (hash=24910686)
 BindingExpression (hash=23511423): Resolve source deferred
    Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=DataContext.IsActive; DataItem=null; target element is 'WaitIndicator' (Name=''); target property is 'DeferedVisibility' (type 'Boolean')
 BindingExpression (hash=23511423): Resolving source 
 BindingExpression (hash=23511423): Found data context element: <null> (OK)
     Lookup name ParentWindow:  queried WaitIndicator (hash=24910686)
 BindingExpression (hash=23511423): Resolving source 
 BindingExpression (hash=23511423): Found data context element: <null> (OK)
     Lookup name ParentWindow:  queried WaitIndicator (hash=24910686)
 BindingExpression (hash=23511423): Resolving source  (last chance)
 BindingExpression (hash=23511423): Found data context element: <null> (OK)
     Lookup name ParentWindow:  queried WaitIndicator (hash=24910686)
Cannot find source for binding with reference 'ElementName=ParentWindow'. BindingExpression:Path=DataContext.IsActive; DataItem=null; target element is 'WaitIndicator' (Name=''); target property is 'DeferedVisibility' (type 'Boolean')

Эти две строки выглядят мне интересно:

BindingExpression (hash=23511423): Found data context element: <null> (OK)
    Lookup name ParentWindow:  queried WaitIndicator (hash=24910686)

Почему DataContext равно нулю? Что-то еще мне не хватает?


edit

После адаптации изменений от @Andy свойство связалось правильно, но все еще что-то не хватает. Пользовательский интерфейс не обновляется. Я уверен, что событие INotifyPropertyChanged реализовано правильно. Журнал печатает это:

System.Windows.Data Warning: 56 : Created BindingExpression (hash=1669504) for Binding (hash=32903719)
System.Windows.Data Warning: 58 :   Path: 'IsActive'
System.Windows.Data Warning: 62 : BindingExpression (hash=1669504): Attach to DevExpress.Xpf.Core.WaitIndicator.DeferedVisibility (hash=14696841)
System.Windows.Data Warning: 67 : BindingExpression (hash=1669504): Resolving source 
System.Windows.Data Warning: 70 : BindingExpression (hash=1669504): Found data context element: <null> (OK)
System.Windows.Data Warning: 78 : BindingExpression (hash=1669504): Activate with root item MainWindowViewModel (hash=42302050)
System.Windows.Data Warning: 108 : BindingExpression (hash=1669504):   At level 0 - for MainWindowViewModel.IsActive found accessor ReflectPropertyDescriptor(IsActive)
System.Windows.Data Warning: 104 : BindingExpression (hash=1669504): Replace item at level 0 with MainWindowViewModel (hash=42302050), using accessor ReflectPropertyDescriptor(IsActive)
System.Windows.Data Warning: 101 : BindingExpression (hash=1669504): GetValue at level 0 from MainWindowViewModel (hash=42302050) using ReflectPropertyDescriptor(IsActive): 'False'
System.Windows.Data Warning: 80 : BindingExpression (hash=1669504): TransferValue - got raw value 'False'
System.Windows.Data Warning: 89 : BindingExpression (hash=1669504): TransferValue - using final value 'False'

Выглядит пока хорошо - модель просмотра может быть найдена. Однако эта строка все еще кажется проблемой.

System.Windows.Data Warning: 70 : BindingExpression (hash=1669504): Found data context element: <null> (OK)

обновленный XAML выглядит следующим образом

<dx:LoadingDecorator Panel.ZIndex="5"
                                 Grid.Row="1"
                                 Grid.Column="1">
    <dx:LoadingDecorator.SplashScreenTemplate  >
        <DataTemplate >
            <dx:WaitIndicator 
                    DeferedVisibility="{Binding Source={StaticResource ResourceKey=mainVM}, 
                        Path=IsActive, 
                        diag:PresentationTraceSources.TraceLevel=High, 
                        Mode=TwoWay, 
                        NotifyOnSourceUpdated=True, 
                        NotifyOnTargetUpdated=True, 
                        UpdateSourceTrigger=PropertyChanged}"
                    Content="Loading" />
        </DataTemplate>
    </dx:LoadingDecorator.SplashScreenTemplate>

Похоже, что все еще что-то не так.


edit 2: В итоге я использовал WaitIndicator напрямую, без DataTemplate. Это работает и производит желаемый результат. Однако я до сих пор не понимаю, почему мой первоначальный подход не работает.

1 Ответ

0 голосов
/ 10 октября 2019

Datacontext помечен как наследуемый, поэтому любой элемент управления в визуальном дереве вашего окна будет наследовать datacontext окна vm: MainWindowViewModel.

Кажется, что этот элемент управления не находится в визуальном дереве, что означает, что онневозможно найти текстовый текст.

После того, как вы переместили модель представления из ресурсов окна и сослались на нее оттуда.

<Window ......    

     DataContext="{DynamicResource vm}"
    >
<Window.Resources>
    <local:MainWindowViewmodel x:Key="vm"/>
</Window.Resources>

Это все еще не работает.

Значениешаблон применяется как-то за пределами окна. Не зная больше о том, что такое элемент управления и как применяется шаблон, это все, что я могу сказать.

...