2017-03-16 20 views
0

我需要返回一個文本作爲System.Window.Shapes形狀(不要問爲什麼,它的任務)。由於沒有文字形狀,我以爲我可以添加一個文本到透明的矩形,但事實證明,與我在網上發現的所有東西一樣,生成的文本看起來不太好,但更糟糕的是:它的繪製與一些討厭的文物:將文本添加到System.Windows.Shapes.Shape代碼後面,

它看起來像文本上方的蓋板被切斷,附加在底部(如文本的一些溢出)

這是我做的方式它(Need to add text to rectangle):

Rectangle r = new Rectangle(); 
    r.Stroke = Brushes.Transparent; 
    r.StrokeThickness = 1; 
    r.VerticalAlignment = VerticalAlignment.Top; 
    r.HorizontalAlignment = HorizontalAlignment.Left; 
    r.Margin = new Thickness(0); 
    r.Width = 200; 
    r.Height = 200; 
    r.RenderTransform = new TranslateTransform(100, 100); 
    TextBlock TB = new TextBlock(); 
    TB.Text = "TEST"; 
    var ft = new FormattedText(
       TB.Text, 
       CultureInfo.CurrentCulture, 
       FlowDirection.LeftToRight, 
       new Typeface("Verdana"), 
       16, 
       Brushes.Black); 
    r.Width = ft.Width; 
    r.Height = ft.Height; 
    //The next two magical lines create a special brush that contains a bitmap rendering of the UI element that can then be used like any other brush and its in hardware and is almost the text book example for utilizing all hardware rending performances in WPF unleashed 4.5 
    BitmapCacheBrush bcb = new BitmapCacheBrush(TB); 
    r.Fill = bcb; 

有人可以解釋爲什麼會發生這種情況,也許會提供解決方法嗎?試圖玩厚度,填充等,但它沒有給出預期的結果。 我將不勝感激任何幫助!已經感謝

+0

*「因爲我實現一個接口」 * - 你能解釋一下嗎?從所提到的問題中解決方案中重疊的'TextBlock'元素(只需將其添加到'Canvas'中)是實現您需要的典型和簡單的方法。 – Sinatr

+0

Okey也許我不清楚:界面迫使我將文本作爲形狀返回。由於沒有Shape,我創建了一個包含Text的Rectangle。 – JAAAAY

+0

我也將它添加到Canvas(通過綁定一個可觀察的集合)在所需的位置(請參閱。Translate Transform(x,y)),但這並沒有幫助。 – JAAAAY

回答

0

使用MVVM和數據模型很容易實現您想要的功能。下面是一個簡單的演示給你的想法。

XAML:

<ItemsControl ItemsSource="{Binding Items}"> 
    <ItemsControl.Resources> 
     <DataTemplate DataType="{x:Type local:TextItem}"> 
      <TextBlock Text="{Binding Text}" /> 
     </DataTemplate> 
     <DataTemplate DataType="{x:Type local:ShapeItem}"> 
      <ContentControl Content="{Binding Shape}" /> 
     </DataTemplate> 
    </ItemsControl.Resources> 
    <ItemsControl.ItemsPanel> 
     <ItemsPanelTemplate> 
      <Canvas /> 
     </ItemsPanelTemplate> 
    </ItemsControl.ItemsPanel> 
    <ItemsControl.ItemContainerStyle> 
     <Style TargetType="ContentPresenter"> 
      <Setter Property="Canvas.Left" Value="{Binding Left}" /> 
      <Setter Property="Canvas.Top" Value="{Binding Top}" /> 
     </Style> 
    </ItemsControl.ItemContainerStyle> 
</ItemsControl> 

CS:

public class Item 
{ 
    public double Left { get; set; } 
    public double Top { get; set; } 
} 

public class ShapeItem : Item 
{ 
    public Shape Shape { get; set; } 
} 

public class TextItem : Item 
{ 
    public string Text { get; set; } 
} 

public partial class MainWindow : Window 
{ 
    public List<object> Items { get; } = new List<object> 
    { 
     new ShapeItem { Shape = new Rectangle { Width = 100, Height = 100, Fill= Brushes.Yellow, Stroke = Brushes.Red }, Left = 10, Top = 10 }, 
     new TextItem { Text= "Lalala", Left = 50, Top = 50 }, 
    }; 

    public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 
    } 
} 

這裏是輸出:

這不是100%MVVM(爲簡單起見),但想法是爲文本和形狀設置不同的數據模板。他們有不同的視角模型:TextItemShapeItem,並相應地顯示爲TextBlockContentControl

另一件事是使用ItemsControl能夠綁定到集合Items並設置Canvas.Left/Canvas.Top屬性。

待辦事項:使用ObservableCollection,對視圖模型實施INotifyPropertyChanged,不要在視圖模型(畫筆,形狀等)中使用視圖元素。

0

雖然我很欣賞給出所有的答案,我已經找到了解決辦法:

簡單的文本塊的字體大小設置爲您在formattedText使用來計算文本的寬度和高度尺寸相同:

tb.Fontsize = 16; ...

這樣不僅文本「溢出」消失,但文本看起來不錯,銳利

相關問題