2009-05-26 9 views
1

Wie bestimmen Sie die Breite des Textes in einem WPF TreeViewItem zur Laufzeit?Wie bestimmen Sie die Breite des Textes in einem WPF-TreeViewItem zur Laufzeit?

Ich brauche einen Offset zu berechnen, so dass ich eine Linie von einem Blatt auf das Blatt einer unterschiedlichen TreeView ziehen. Alle 'width'-Eigenschaften geben eine Größe zurück, die viel größer ist als der Platz, der vom tatsächlichen Text des Knotens eingenommen wird. Dies muss möglich sein, da die Select-Funktion nicht die gesamte Zeile hervorhebt. Ich schreibe den Client in WPF und Silverlight.

Antwort

0

Ich habe zwei Lösungen:

A) Verwendet die visuelle Struktur

TreeViewItem selected = (TreeViewItem)dataSourceTreeView.SelectedItem; 
    double textWidth = 0; 
    double expanderWidth = 0; 
    Grid grid = (Grid)VisualTreeHelper.GetChild(selected, 0); 

    ToggleButton toggleButton = (ToggleButton)VisualTreeHelper.GetChild(grid, 0); 
    expanderWidth = toggleButton.ActualWidth; 

    Border bd = (Border)VisualTreeHelper.GetChild(grid, 1); 
    textWidth = bd.ActualWidth; 

B) Wenn Sie nicht die visuelle Struktur

TreeViewItem selected = (TreeViewItem)dataSourceTreeView.SelectedItem; 
    double textWidth = 0; 
    Typeface typeface = new Typeface(selected.FontFamily, 
     selected.FontStyle, selected.FontWeight, selected.FontStretch); 

    GlyphTypeface glyphTypeface; 
    if (!typeface.TryGetGlyphTypeface(out glyphTypeface)) 
      throw new InvalidOperationException("No glyphtypeface found"); 

    string headerText = (string)selected.Header; 
    double size = selected.FontSize; 

    ushort[] glyphIndexes = new ushort[headerText.Length]; 
    double[] advanceWidths = new double[headerText.Length]; 

    for (int n = 0; n < headerText.Length; n++) 
    { 
      ushort glyphIndex = glyphTypeface.CharacterToGlyphMap[headerText[n]]; 
      glyphIndexes[n] = glyphIndex; 

      double width = glyphTypeface.AdvanceWidths[glyphIndex] * size; 
      advanceWidths[n] = width; 

      textWidth += width; 
    } 
1

Sie waren auf den Text oder die Tags nicht sehr spezifisch, so dass ich nehme an, dass Sie über das .NET Framework TreeViewItem einnehmen.

Es könnte einfache Art und Weise sein, aber eine Möglichkeit ist, die Graphics.MeasureString Methode zu verwenden. Sie erhalten die Größe eines Textes in Pixeln, wenn er mit einer bestimmten Schriftart gezeichnet wird.

+0

Ja, meine ich t .Net. Ich hätte genauer sein sollen. Ich schreibe den Client in WPF und Silverlight. FEST. – MrPhil

+0

Der System.Drawing-Namespace ist in Silverlight nicht verfügbar und von dem, was ich sagen kann, gibt es keine gleichwertige Methode um – MrPhil

1

@mrphil verwenden wollen: Süß Abgebrochener Fötus, das ist gruselig

myTreeViewItem.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); 
Size s = myTreeViewItem.DesiredSize; 
return s.Width; 
+0

Danke für den Versuch, aber Sie antworten, funktioniert nicht für mich, weil: 1. Sie einen Tippfehler haben. DesireSize ist eine Eigenschaft, keine Methode, also die(). 2. Sie werden feststellen, dass dies tatsächlich die Breite des gesamten Baums ergibt, nicht dieses bestimmte Element. 3. Die Größe, die es meldet, scheint eine Art Padding zu beinhalten und ist immer noch größer als die Antwort, die mein Code meldet. – MrPhil

+0

Ok - in diesem Fall benutze Snoop (http://blois.us/Snoop/) um eine passende Sache zu finden –

+0

Cooles Werkzeug! Vielen Dank! – MrPhil