XAMLを使用してPNGボタンを作成するためのプロトタイプを作成しています。基本的な考え方は、グッドなグラデーション画像ボタンは、ローカライズされた文字列から生成することができます。XAMLボタンをPNGにレンダリングするときの動的な高さと幅
私が実際に見つけた最も単純な例は、C#アセンブリとcall it from PHPを構築することでした。私はそれを純粋なC#に変換しました。私の基本的に動作するプロトタイプの外観は次のとおりです。
XAMLファイルは次のようになります。私が欲しいもの
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ファイルです:
<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のは次のようになりますボタンの文字列がスワップアウトされました。私のプロトタイプは基本的なレベルで動作し、入力されたXAMLファイルからイメージをレンダリングします。
ただし、XAMLファイルでは、高さと幅を明示的に指定しています。これは、あらかじめ幅がわかっていないので、ボタン自体の文字列を動的に提供することが問題になります。また、フォントの変更もそれに伴って混乱することになります。
私が探しているのは、実行時に計算された高さと幅、またはテキスト文字列に基づいて事前計算する簡単な方法のいずれかを計算する方法です。何か案は?
私は今日これを試してみます。私は幅と高さを残してみましたが、(2番目のポイントが扱うように)サイズの計算はnullポインタを投げました。私はボタンによって占められている実際のスペースを測定する方法がなければならないと思っていました。あなたの例がまさにそのように見えます。 –
私はそれを試して待つことができなかったので、コメントした直後にそれをしました。私が変更しなければならなかったのは、コンパイラがdoubleを好きではなかったということだけでした.Infinityとdoubleに変更する必要がありました.PositiveInfinityまた、グリッドレイアウトを変更することなく機能しました。しかし、これについて明示的に説明することはおそらく正しい方法なので、私はXAMLにそれを含めます。 答えをPositiveInfinityフィールドに変更できる場合は、答えを確定としてマークします。 –