TabControl
プログラムでオブジェクトに動的に追加される複数のタブがあるプログラムがあります。私がやりたいのは、これらの各タブのコンテンツ値をPNGにレンダリングすることです。StackOverflowまたはおそらくGoogle(ソースを失った)の他の場所で取得したスクリプトを使用しています。私のコードは次のようになります。
if (tabPanel.Items.Count > 0)
{
SaveFileDialog fileDialog = new SaveFileDialog();
fileDialog.Filter = "PNG|*.png";
fileDialog.Title = "Save Tabs";
fileDialog.ShowDialog();
if (fileDialog.FileName.Trim().Length > 0)
{
try
{
string filePrefix = fileDialog.FileName.Replace(".png", "");
int tabNo = 1;
foreach (TabItem tabItem in tabPanel.Items)
{
string filename = filePrefix + "_" + tabNo + ".png";
TabContentControl content = tabItem.Content as TabContentControl;
Rect rect = new Rect(content.RenderSize);
RenderTargetBitmap rtb = new RenderTargetBitmap((int)rect.Right, (int)rect.Bottom, 96d, 96d, System.Windows.Media.PixelFormats.Default);
rtb.Render(content);
BitmapEncoder pngEncoder = new PngBitmapEncoder();
pngEncoder.Frames.Add(BitmapFrame.Create(rtb));
System.IO.MemoryStream ms = new System.IO.MemoryStream();
pngEncoder.Save(ms);
System.IO.File.WriteAllBytes(filename, ms.ToArray());
ms.Close();
tabNo++;
}
}
catch (Exception ex)
{
// log exception
}
}
}
このコードを呼び出す前にレンダリングする必要のあるすべてのタブを確認して確認した場合、このコードは希望どおりに機能します。先に進み、TabContentControlからレンダリングされた正しいコンテンツを使用してfilePrefix_1.png、filePrefix_2.pngなどを作成します。ただし、すべてのタブを表示する前にこのコードを使用するハンドラーを呼び出すと、コードはで例外をスローnew RenderTargetBitmap(...)
しcontent.RenderSize
ます{0.0, 0.0}
。表示されていないタブのレンダリングサイズを一度表示されたタブの1つに強制しようとすると、出力されたPNGは正しいサイズですが、完全に空です。
したがって、TabContentControlのレンダリングを強制する方法が必要だと思います。Renderイベントは、UIElementをレンダリングする必要がある場合にのみ実行されるようです。これを回避するために私が実行できるトリックはありますか?
また、Page_Loadedイベントハンドラーでタブの作成時に次のコードを追加することにより、WPFを「だまして」タブコンテンツをペイントしようとしました。
void Page_Loaded(object sender, RoutedEventArgs e)
{
// irrelevant code
foreach (// iterate over content that is added to each tab)
{
TabItem tabItem = new TabItem();
// load content
tabPanel.Items.Add(tabItem);
tabItem.IsSelected = true;
}
// tabPanel.SelectedIndex = 0;
}
ハンドラーの最後の行Page_Loaded
がコメント化されると、最後のタブにフォーカスがRenderSize
置かれ、そのコンテンツに対してプロパティが定義されます。最後の行がコメントアウトされていない場合、最初のタブにフォーカスがあり、同じ動作をします。他のタブにはレンダリング情報がありません。