2017-06-16 84 views
2

我試圖將工具提示的PlacementTarget更改爲視覺樹上的一個窗口,以便在該窗口中具有自定義工具提示裁剪效果。除了PlacementTarget之外,我已經吸引了所有人。這裏有一個來自XAML和代碼的例子......都不起作用。此樣式當前正在用於連接到TextBox的單個工具提示。C#WPF:更改工具提示的PlacementTarget

<Style TargetType="ToolTip"> 
    <Setter Property="ToolTipService.PlacementTarget" 
      Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, 
       AncestorType={x:Type Grid }} }" /> 
</Style> 

如果我進入代碼,並期待在tooltip.PlacementTarget一旦它的附加的東西......它總是設置爲文本框。我嘗試過使用VisualTree獲取不同UIElements的多種方式。似乎沒有任何工作......所以我假設我不理解或錯過某些東西。

真正讓我感到意外的是,如果我進入我的代碼並查看工具提示的PlacementTarget,它不會讓我將其設置爲其他任何內容。例如:

var ancestors = toolTip.PlacementTarget.GetSelfAndAncestors(); 

foreach(var ancestor in ancestors) 
{ 
    if(var ancestor is Grid) 
    { 
     // Conditional always hits. 
     // Before this line, PlacementTarget is a TextBox. 
     toolTip.PlacementTarget = (UIElement)ancestor; 
     // After the line, PlacementTarget is still a TextBox. 
    } 
} 

我在做什麼不正確或不理解?

上下文編輯:自定義剪切效果基本上只是找到最接近的工具提示目標的祖先窗口,並使用它來確保工具提示永遠不會超出該窗口的範圍。

+0

WPF的工具提示與PlacementTarget和DataContext一起工作的方式有些雜亂。它獲得配置快速使用;看看在https://stackoverflow.com/questions/6783693/how-to-set-a-placementtarget-for-a-wpf-tooltip-without-messing-up-the-datacontex –

+0

你的視覺樹如何定義?工具提示駐留在自己的可視化樹中,並且無法使用RelativeSource在父窗口中查找某些內容。 – mm8

+0

@TimothyGroote謝謝,我會檢查出來。對於mm8,我認爲RelativeSource值首先會定位到默認目標(在這種情況下是TextBox),然後向上移動它們的可視化樹來查找第一個Grid(可能需要將AnscestorLevel設置爲1)。但是,無論如何,我無法真正設置PlacementTarget。 – user2079828

回答

2

設置Tooltip的簡短示例,使用父級Window的屬性作爲PlacementTarget

<Window x:Class="WpfApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Tag="Bar"> 
    <Window.Resources> 
     <ToolTip x:Key="FooToolTip"> 
      <StackPanel> 
       <TextBlock Text="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}"/> 
      </StackPanel> 
     </ToolTip> 
    </Window.Resources> 
    <Grid> 
     <TextBlock 
      Text="Foo" 
      ToolTip="{StaticResource FooToolTip}" 
      ToolTipService.PlacementTarget="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}" 
      HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Width="50"> 
     </TextBlock> 
    </Grid> 
</Window> 

編輯

回答您的問題,

的第一個片段以錯誤的方式使用ToolTipService

的ToolTipService類附加屬性來確定位置,行爲和工具提示的外觀。 這些屬性在定義工具提示的元素上設置。

應用的風格:

<Window x:Class="WpfApp.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" 
     Tag="Bar"> 
    <Window.Resources> 
     <ToolTip x:Key="FooToolTip"> 
      <StackPanel> 
       <TextBlock Text="{Binding PlacementTarget.Tag, RelativeSource={RelativeSource AncestorType={x:Type ToolTip}}}"/> 
      </StackPanel> 
     </ToolTip> 
     <Style x:Key="ToolTipStyle"> 
      <Setter Property="ToolTipService.ToolTip" Value="{StaticResource FooToolTip}"/> 
      <Setter Property="ToolTipService.PlacementTarget" Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}}"/> 
     </Style> 
    </Window.Resources> 
    <Grid> 
     <TextBlock 
      Text="Foo" Style="{StaticResource ToolTipStyle}" 
      HorizontalAlignment="Center" VerticalAlignment="Center" Height="20" Width="50"> 
     </TextBlock> 
    </Grid> 
</Window> 

至於在代碼中你的第二個片段背後,你不能設置PlacementTarget一旦ToolTip是開放的,當ToolTip關閉時PlacementTarget爲null 。正如@ mm8所指出的那樣,這與ToolTipPlacementTarget處於不同的視覺樹中有關,因爲ToolTip產生自己的和Window

+0

我見過這個,它(可能)解決了我的問題,但並沒有真正回答這個問題。這兩個代碼片段究竟有什麼不正確?爲什麼我不能在第二個程序中以編程方式設置PlacementTarget? – user2079828

+0

此外,它需要在工具提示樣式中設置,因爲我沒有將placementTarget放置在我希望樣式使用的每個控件中。 – user2079828

+0

我用你的解釋讓我走了。我能夠通過創建一個行爲的子類來解決它,它將xaml中的屬性附加到任何給定的行爲(基於https://stackoverflow.com/questions/1647815/how-to-add-a-blend-behavior -in-A-風格引領者)。然後我在窗口上放置一個標籤,並使用我的行爲設置工具提示樣式。它搜索與標籤匹配的第一個祖先,並使用其屬性來適應彈出窗口。這允許我爲每個視圖設置一個工具提示樣式,並將標籤放置在我希望工具提示適合的窗口上。不需要單獨控制。 – user2079828