Datatrigger на contentpresenter.content не работает - PullRequest
4 голосов
/ 20 февраля 2012

Я пытаюсь переключить содержимое contentpresenter на основе источника данных. Я хочу отобразить usercontrol в contentpresenter.content, если у меня установлено значение или мне нужно отобразить сообщение об ошибке. Но привязка на мой datatrigger не в состоянии заявить, что свойство не найдено. Я не могу получить datacontext, чтобы унаследовать для проверки datatrigger. Я могу заставить это работать, используя закомментированный код. Но я смущен, почему это не работает нормальным способом.

  <ContentPresenter.Style>
            <Style TargetType="{x:Type ContentPresenter}">
                  <Setter Property="Content" Value="{Binding UC}"/>
                <Style.Triggers>
                    <!--<DataTrigger Binding="{Binding DataContext.HasValue,RelativeSource={RelativeSource AncestorType={x:Type ContentPresenter}}}" Value="false">
                        <Setter Property="Content" Value="No preview"/>
                    </DataTrigger>-->
                    <DataTrigger Binding="{Binding HasValue}" Value="false">
                        <Setter Property="Content" Value="No value"/>
                    </DataTrigger> 

                </Style.Triggers> 

            </Style>
        </ContentPresenter.Style>
    </ContentPresenter>

Ответы [ 2 ]

5 голосов
/ 28 августа 2016

Если вы хотите использовать триггеры для отображения UserControl, вы должны использовать ContentControl, а не ContentPresenter.Я предпочитаю использовать ContentPresenter для CustomControls и когда я использую UserControl для представлений пользовательских типов данных в моей системе и разрешить динамическое поведение.

Пример: для переключения шаблонов для ContentPresenter необходимо установить ContentTemplateSelector следующим образом

<ContentPresenter Content="{Binding MyContent}"
                          ContentTemplate="{Binding MyContentTemplate}"
                          ContentTemplateSelector="{Binding MyContentTemplateSelector}"/>

MyContent, MyContentTemplate & MyContentTemplateSelector являются свойствами зависимости и могут быть связаны, где бы вы ни использовали их экземпляр.

READ :

Использование ContentPresenter

В чем разница между ContentControl и ContentPresenter

Упомянутая в вопросе привязка не будет работать как

ContentContext для ContentPresenter автоматически устанавливается равным значению его свойства Content, а DataContext для ContentControl - нет.

Привязки разрешаются относительно значения свойства DataContext.Если вы объявите привязку в ContentPresenter, то в момент установки его содержимого привязка будет переоценена.

Свойство ContentControl.Content может быть изменено для любого триггера в зависимости от ваших требований.Если вы хотите использовать его для изменения в PropertyChanged Event свойства ViewModel, можно использовать DataTrigger, связав его с DataTemplate с экземпляром UserControl в нем или используя статический ресурс этого UserControl.

<ContentControl>
    <ContentControl.Style>
        <Style TargetType="{x:Type ContentControl}">
            <Setter Value="{StaticResource UnSelectedDataTemplate}" Property="ContentTemplate" />
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=IsSelected}" Value="True">
                    <Setter Value="{StaticResource SelectedDataTemplate}" Property="ContentTemplate" />
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentContro.Style>
</ContentControl>

READ Как использовать триггеры для шаблона содержимого , подробнее здесь

Разница в DataTemplate и StaticResourcescope is DataTemplate создает новый экземпляр шаблона каждый раз, когда он применяется.Принимая во внимание, что StaticResource снова использует тот же экземпляр UserControl (Static Instance).Вы также можете использовать EventTriggers для изменения базы контента, например, MouseOver и т. Д.

Альтернативный подход
Очень похоже на вышеприведенное с небольшой разницей.Определение в качестве шаблона данных в ресурсах.Запуск по изменению контента по сути идентичен.

... в теге <x.Resources />:

<DataTemplate x:Key="DesignerTemplate" DataType="{x:Type vm:SolutionViewModel}">
    <vw:SolutionDesignerView />
</DataTemplate>
<DataTemplate DataType="{x:Type vm:SolutionViewModel}">
    <ContentControl Content="{Binding }">
        <ContentControl.Style>
            <Style TargetType="{x:Type ContentControl}">
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsLoaded}" Value="True">
                        <Setter Property="ContentTemplate" Value="{StaticResource DesignerTemplate}" />
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </ContentControl.Style>
    </ContentControl>
</DataTemplate>

... затем:

<ContentControl Content="{Binding Solution}" />  
0 голосов
/ 20 февраля 2012

Я обычно использую триггер Как это ...

                        <UserControl>
                            <UserControl.Resources>
                                <DataTemplate x:Key="normalTemplate" >
                                     <!-Fav UserControl->
                                </DataTemplate >
                                <DataTemplate x:Key="overWriteTempalte">
                                    <!-Fav UserControl->                                    </DataTemplate>
                            </UserControl.Resources>
                            <ContentPresenter x:Name="ContentField"
                                              Content="{Binding}"
                                              ContentTemplate="{StaticResource ResourceKey=normalTemplate}" />
                            <UserControl.Triggers>
                                <DataTrigger Binding="{Binding Path=MyProperty}" Value="True">
                                    <Setter TargetName="ContentField" Property="ContentTemplate" Value="{StaticResource ResourceKey=overWriteTempalte}" />
                                </DataTrigger>
                            </UserControl.Triggers>
                        </UserControl>

Если привязки являются проблемой Используйте Snoop для обнаружения ошибок привязки

...