【问题标题】:Change Template of ContentControl with Trigger使用触发器更改 ContentControl 的模板
【发布时间】:2012-04-26 22:22:06
【问题描述】:

我有一个包含许多项目的列表框。当我将鼠标悬停在一个项目上时,我需要显示一个相当“沉重”的弹出窗口。我很确定为每个项目加载弹出窗口是一种资源浪费,所以我想要的只是当我将鼠标悬停在项目上时,我修改项目中 ContentControl 的模板以包含弹出窗口。这是我目前所拥有的:(简化版)(这段代码可以粘贴到 Kaxaml 中)

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources> 

    <ControlTemplate x:Key="WithPopup" TargetType="ContentControl">
      <Grid>
        <ContentPresenter Content="{TemplateBinding Content}" Name="Target" />
        <Popup PlacementTarget="{Binding ElementName=Target}" IsOpen="True" >
            <Border BorderBrush="Red" BorderThickness="1" Background="Pink"> 
                <TextBlock Text="I'd like this to behave like a Popup - not a tooltip!" Margin="10" /> 
            </Border> 
        </Popup> 
      </Grid>
    </ControlTemplate>   
  </Page.Resources>
  <Grid Height="20" Margin="50,50,0,0" Name="ParentGrid">  
    <ContentControl>
      <TextBlock x:Name="TargetControl" Text="Hover over me!"  /> 
      <ContentControl.Style>
        <Style TargetType="ContentControl">
          <Style.Triggers>
            <DataTrigger Binding="{Binding IsMouseOver, ElementName=TargetControl}" Value="True">
              <Setter Property="Template" Value="{StaticResource WithPopup}" />
            </DataTrigger>
          </Style.Triggers>
        </Style>
      </ContentControl.Style>
    </ContentControl>
  </Grid>
</Page>

问题是,当我尝试将鼠标悬停在弹出窗口上时 - 它会消失(就像工具提示一样),因为我是鼠标离开了原始 ControlTemplate - 这会导致带有弹出窗口的模板消失。有任何想法吗? 编辑:我也有可用的代码隐藏来实现这一点(即使我更喜欢 xaml)

【问题讨论】:

    标签: wpf popup contentcontrol


    【解决方案1】:

    我有我认为(至少部分)的解决方案: 不是通过触发器更改 ContentControl 的模板,而是更改 Popup 的 触发器的内容似乎有效。因此,我没有为每个项目加载一个带有大型可视化树的复杂弹出窗口,而是为每个项目加载一个没有内容的简单弹出窗口 - 并且仅在鼠标输入 ContentControl 时填充该内容。像这样:

    <Page
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
      <Page.Resources>
        <DataTemplate x:Key="popupContent" DataType="{x:Type ContentControl}">
          <Border BorderBrush="Red" BorderThickness="1" Background="Pink"> 
              <TextBlock Text="This is behaving like a Popup now!" Margin="10" /> 
          </Border>
        </DataTemplate>
    
        <ControlTemplate x:Key="WithPopup" TargetType="ContentControl">
          <Grid Name="popupGrid">
            <TextBlock Text="Hover over me!"  />
            <Popup IsOpen="True" > 
                <ContentControl Name="content" />
            </Popup> 
          </Grid>
          <ControlTemplate.Triggers>
            <DataTrigger Binding="{Binding IsMouseOver, ElementName=popupGrid}" Value="True"> 
              <Setter Property="ContentTemplate" Value="{StaticResource popupContent}"  TargetName="content" />
            </DataTrigger>
          </ControlTemplate.Triggers>
        </ControlTemplate>
    
      </Page.Resources>
      <Grid Height="20" Width="100" HorizontalAlignment="Left" Margin="50,50,0,0">  
        <ContentControl Template="{StaticResource WithPopup}" />
      </Grid>
    </Page>
    

    我不太确定如何衡量使用这种方法在性能方面会获得多少收益,但我认为这似乎是有道理的。我仍然想听听任何其他更好的想法。 谢谢。

    【讨论】:

      【解决方案2】:

      你需要做一些不同的事情 - 尝试这样的事情:

      <ContentControl Content="hover over me!">
          <ContentControl.ContentTemplate>
              <DataTemplate>
                  <Grid>
                      <TextBlock x:Name="TargetControl" Text="{TemplateBinding Content}"  />
                      <Popup PlacementTarget="{Binding ElementName=Target}" x:Name="popup">
                          <Border BorderBrush="Red" BorderThickness="1" Background="Pink">
                              <TextBlock Text="I'd like this to behave like a Popup - not a tooltip!" Margin="10" />
                          </Border>
                      </Popup>
                  </Grid>
                  <DataTemplate.Triggers>
                      <DataTrigger Binding="{Binding IsMouseOver, ElementName=TargetControl}" Value="True">
                          <Setter TargetName="popup" Property="IsOpen" Value="true" />
                      </DataTrigger>
                      <DataTrigger Binding="{Binding IsMouseOver, ElementName=popup}" Value="true">
                          <Setter TargetName="popup" Property="IsOpen" Value="true" />
                      </DataTrigger>
                  </DataTemplate.Triggers>
              </DataTemplate>
          </ContentControl.ContentTemplate>
      </ContentControl>
      

      【讨论】:

      • 嗨,Dean,感谢您的回答,但我正在寻找一种解决方案,我不必为每个项目加载弹出窗口 - 仅适用于我鼠标悬停的项目。在您的解决方案中 - 弹出窗口已加载 - 只是不可见
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多