2009-08-04 20 views
0

我正在製作一個使用XAML創建PNG按鈕的原型。基本思想是,可以從本地化的字符串生成漂亮的漸變圖像按鈕,而不是通過任何類型的圖形部門創建它們。將XAML按鈕渲染爲PNG時的動態高度和寬度

我發現的最直接的例子實際上是構建一個C#程序集和call it from PHP。我將它轉換爲純C#。這是我的基本工作原型的樣子。

XAML文件看起來像:

<UserControl 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
mc:Ignorable="d" 
Width="640" Height="480"> 

<Grid x:Name="LayoutRoot"> 
    <Button HorizontalAlignment="Left" VerticalAlignment="Top" Content="Add To Cart" FontFamily="Arial" FontSize="11" Height="24" FontWeight="Bold" Margin="0,3,0,0"> 
     <Button.Background> 
      <LinearGradientBrush EndPoint="0,1" StartPoint="0,0"> 
       <GradientStop Color="#FFF3F3F3" Offset="0"/> 
       <GradientStop Color="#FFEBEBEB" Offset="0.5"/> 
       <GradientStop Color="#FFDDDDDD" Offset="0.502"/> 
       <GradientStop Color="#FFCDCDCD" Offset="1"/> 
      </LinearGradientBrush> 
     </Button.Background> 
    </Button> 
</Grid> 

的Program.cs的樣子:

class Program 
{ 
    static void Main(string[] args) 
    { 
     FileInfo xamlFile = new FileInfo("Button.xaml"); 
     var inputXaml = File.ReadAllText(xamlFile.FullName); 
     Thread pngCreationThread = new Thread((ThreadStart) delegate() 
      { 
       GenImageFromXaml(inputXaml); 
      }); 
     pngCreationThread.IsBackground = true; 
     pngCreationThread.SetApartmentState(ApartmentState.STA); 
     pngCreationThread.Start(); 
     pngCreationThread.Join(); 
    } 
    public static void GenImageFromXaml(string xaml) 
    { 
     var element = (FrameworkElement)XamlReader.Parse(xaml); 
     var pngBytes = GetPngImage(element); 

     using(BinaryWriter binWriter = 
     new BinaryWriter(File.Open(@"output.png", FileMode.Create))) 
     { 
      binWriter.Write(pngBytes); 
     } 
    } 
    private static byte[] GetPngImage(FrameworkElement element) 
    { 
     var size = new Size(element.Width, element.Height); 
     element.Measure(size); 
     element.Arrange(new Rect(size)); 
     var renderTarget = 
      new RenderTargetBitmap((int)element.RenderSize.Width, 
           (int)element.RenderSize.Height, 
           96, 96, 
           PixelFormats.Pbgra32); 
     var sourceBrush = new VisualBrush(element); 
     var drawingVisual = new DrawingVisual(); 
     using (DrawingContext drawingContext = drawingVisual.RenderOpen()) 
     { 
      drawingContext.DrawRectangle(
       sourceBrush, null, new Rect(
             new Point(0, 0), 
             new Point(element.RenderSize.Width, 
             element.RenderSize.Height))); 
     } 
     renderTarget.Render(drawingVisual); 
     var pngEncoder = new PngBitmapEncoder(); 
     pngEncoder.Frames.Add(BitmapFrame.Create(renderTarget)); 
     using (var outputStream = new MemoryStream()) 
     { 
      pngEncoder.Save(outputStream); 
      return outputStream.ToArray(); 
     } 
    } 
} 

我要的是一個可以作爲模板與實際XAML文件換出按鈕中的字符串。我的原型在基本級別上工作,從輸入的XAML文件中渲染圖像。

但是,XAML文件明確指定了高度和寬度。這將是一個問題,因爲按鈕本身的字符串是動態提供的,因爲事先不會知道寬度,並且任何字體修改都會混淆它。

我正在尋找的是一種在運行時計算高度和寬度或基於文本字符串預先計算它們的直接方法。有任何想法嗎?

回答

2

你可以嘗試follwing

1不要在XAML中設置寬度和高度

2更換你測量/安排該電話:

​​3210

措施都將根據該DesiredSize財產在你通過它的大小上,這可能是你想要的大小。

3(不確定是否需要)將Grid(LayoutRoot)設置爲Top/Left對齊方式,因爲Grid默認採用所有可用大小,您不需要。

+0

我今天試試。我曾嘗試將寬度和高度留下,但是(如你的第二點處理)尺寸計算拋出空指針。我認爲必須有一種方法來衡量按鈕佔用的實際空間,看起來你的例子就是這樣。 – 2009-08-04 13:12:39