TabControl
개체에 프로그래밍 방식으로 동적으로 추가 된 탭이있는 프로그램이 있습니다. 내가하고 싶은 일은 이러한 각 탭의 Content 값을 PNG로 렌더링하는 것입니다. 나는 StackOverflow 나 다른 곳에서 픽업 한 스크립트를 사용하고있다. 내 코드는 다음과 같습니다 : 원하는대로TabControl의 다른 탭에서 콘텐츠 컨트롤 렌더링
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 등을 만듭니다. 그러나 모든 탭을보기 전에이 코드를 사용하는 핸들러를 호출하면 content.RenderSize
이 {0.0, 0.0}
이기 때문에 코드에서 new RenderTargetBitmap(...)
에 예외가 발생합니다. 볼 수없는 탭의 렌더링 크기를 한 번 보았을 때 출력 된 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
속성이 정의되어 있습니다. 마지막 줄을 주석 처리하지 않으면 첫 번째 탭에 포커스가 있으며 같은 동작을합니다. 다른 탭에는 렌더링 정보가 없습니다.
비슷한 일을 시도했지만 나에게있어 보이는 탭을 프로그래밍 방식으로 변경하는 방법을 찾지 못했습니다. 'TabControl.SelectedItem'을'TabItem'으로 설정하려고 시도하고'TabControl.SelectedIndex' 속성을 증가 시키려고 시도했습니다. – sohum
사실 ..... 방금 처리기 내에서 저장 버튼을 클릭 한 후 탭을 변경하려고했는데 탭이 다시 그려지는 기회가 없다고 생각했습니다. 탭을 추가 할 때 이렇게하면 문제가되지 않습니다. – sohum
그냥 시도했지만 작동하지 않았습니다. WPF는 최적화 된 것으로 보이고 마지막 탭만 페인트합니다. – sohum