Состояние флажка WPF не обновляется в FixedPage
Я пытаюсь экспортировать некоторые данные на основе элемента FixedPage, используемого в качестве шаблона в WPF, и у меня, похоже, возникают проблемы с обновлением значения флажков. Странная часть заключается в том, что я также использую текстовые блоки и текстовые поля в своем шаблоне, но у них нет проблем с обновлением их содержимого.
Итак... с самого начала. Данные, которые я хочу экспортировать, находятся в классе с именем RepairStatement, который позволяет печатать в пользовательский файл xps с помощью функции printForm.
public class RepairStatement
{
// Variables
public bool hasKulanz { get; set; }
public bool hasRepair { get; set; }
public Client client { get; set; }
/// <summary>
/// Export repair statement to XPS file.
/// </summary>
/// <param name="file">output xps file</param>
public void printForm(string file)
{
string printTemplateRepairStatementPath = "Print Templates\\RepairStatement.xaml";
// Define general purpose handlers to be used in browsing the print templates
FileStream fileStream;
if (!File.Exists(file))
{
FileStream newfile = File.Create(file);
newfile.Close();
}
// Check that all xaml templates exist
if (!File.Exists(printTemplateRepairStatementPath))
{
throw new ArgumentNullException(printTemplateRepairStatementPath,
"Repair Statement print template is not available. Check file source");
}
FixedDocument doc = new FixedDocument();
// A4 Standard: 8.27 x 11.69 inch; 96 dpi
Size documentSize = new Size(96 * 8.27, 96 * 11.69);
doc.DocumentPaginator.PageSize = documentSize;
// 1. Reparatur-Bericht
// a. Open the filestream
try
{
fileStream = new FileStream(printTemplateRepairStatementPath, FileMode.Open);
}
catch (Exception e)
{
throw new ArgumentNullException(LoginAgent.userSerializationPath,
"Repair Statement print template could not be open due to " + e.Message);
}
// b. Read the XAML tree
FixedPage fixedPage = XamlReader.Load(fileStream) as FixedPage;
// c. Set the data
(fixedPage.FindName("receiptAddress") as TextBox).Text = client.receiptAddress; // Works
(fixedPage.FindName("deliveryAddress") as TextBox).Text = client.deliveryAddress;// Works
(fixedPage.FindName("hasEndorser") as CheckBox).IsChecked = true; // Has no effect
// d. Set the page size
fixedPage.Width = doc.DocumentPaginator.PageSize.Width;
fixedPage.Height = doc.DocumentPaginator.PageSize.Height;
// Add to document
PageContent pageContent = new PageContent();
((IAddChild)pageContent).AddChild(fixedPage);
doc.Pages.Add(pageContent);
// Convert to XPS
XpsDocument xpsDocument = new XpsDocument(file, FileAccess.Write);
XpsDocumentWriter documentWriter = XpsDocument.CreateXpsDocumentWriter(xpsDocument);
documentWriter.Write(doc);
xpsDocument.Close();
}
}
Шаблон xaml, который я использую, выглядит следующим образом:
<FixedPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
Name="RepairStatementFixedPage"
Background="White"
Width="793.92" Height="1122.24" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Border Name="bigPage" BorderThickness="1" BorderBrush="#FFCB9999" Width="793.92" Height="1122.24"
HorizontalAlignment="Center" VerticalAlignment="Center">
<Border Name="content" Margin="96, 96">
<DockPanel LastChildFill="False">
<Grid DockPanel.Dock="Top" Name="title">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="120" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="10" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Grid.RowSpan="3" Width="120"
Source="/DesktopLibrarian;component/Content/lib-bg.jpg"
VerticalAlignment="Top" HorizontalAlignment="Left" />
<TextBlock Grid.Column="1" Grid.RowSpan="3" HorizontalAlignment="Center" VerticalAlignment="Bottom"
TextBlock.FontSize="23">
Reparaturbericht
</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="0" Grid.RowSpan="3"
VerticalAlignment="Top" HorizontalAlignment="Right" Name="repairNumber">
TEST
</TextBlock>
</Grid>
<Border DockPanel.Dock="Top" Height="20" />
<Grid DockPanel.Dock="Top" Name="deviceInfo">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>
<!-- Client information -->
<GroupBox DockPanel.Dock="Top" Header="Kundeninformationen">
<Grid Margin="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="110" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Name -->
<TextBlock Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" Name="clientName"
TextBlock.FontWeight="Bold">
TEST
</TextBlock>
<!-- Phone Number -->
<TextBlock Grid.Column="0" Grid.Row="2">Telefonnummer:</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="2" Name="phoneNumber">TEST</TextBlock>
<!-- Auftragsnummer -->
<TextBlock Grid.Column="0" Grid.Row="3">Auftragsnummer (RMA):</TextBlock>
<TextBlock Grid.Column="2" Grid.Row="3" Name="orderNumber">TEST</TextBlock>
<!-- Receipt Address -->
<TextBlock Grid.Column="4" Grid.Row="1">Rechnungsadresse:</TextBlock>
<TextBox Grid.Column="4" Grid.Row="2" Grid.RowSpan="2" Name="receiptAddress" BorderThickness="0"
AcceptsReturn="True" TextWrapping="Wrap">
TEST
</TextBox>
<!-- Delivery Address -->
<TextBlock Grid.Column="6" Grid.Row="1">Lieferadresse:</TextBlock>
<TextBox Grid.Column="6" Grid.Row="2" Grid.RowSpan="2" Name="deliveryAddress" BorderThickness="0"
AcceptsReturn="True" TextWrapping="Wrap">
TEST
</TextBox>
</Grid>
</GroupBox>
<Border DockPanel.Dock="Top" Height="20" />
<!-- Device information -->
<GroupBox DockPanel.Dock="Top" Header="Geräteinformationen">
<Grid Margin="3">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="90" />
<ColumnDefinition Width="3" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="8" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Model -->
<TextBlock Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="0" Name="model" TextBlock.FontWeight="Bold">
TEST
</TextBlock>
<!-- Repair -->
<CheckBox Grid.Column="4" Grid.Row="1" Name="hasRepair">Reparatur</CheckBox>
<!-- Device has endorser -->
<CheckBox Grid.Column="4" Grid.Row="2" Name="hasEndorser">Endorsergerät</CheckBox>
</Grid>
</GroupBox>
</DockPanel>
</Border>
</Border>
Проблема в этих 3 строках функции printForm:
// c. Set the data
(fixedPage.FindName("receiptAddress") as TextBox).Text = client.receiptAddress;
(fixedPage.FindName("deliveryAddress") as TextBox).Text = client.deliveryAddress;
(fixedPage.FindName("hasEndorser") as CheckBox).IsChecked = true;
Первые две строки изменяют содержимое текстового поля как обычно. Я также могу без проблем изменять содержимое текстовых блоков, но значения для флажков не меняются, независимо от того, что я пытаюсь сделать. Я предполагаю, что это как-то связано с FixedPage или FixedDocument, но я не могу понять, в чем проблема. Если я установлю IsChecked="True" в XAML, флажок будет отображаться как отмеченный в окончательном документе xps, но аналогично я не могу снять его.
Будем очень благодарны за любые подсказки относительно того, что может пойти не так. Если вы знаете о хороших учебных пособиях или источниках информации для FixedPage и FixedDocument, я хотел бы также взглянуть на них, поскольку документация, которую я нашел до сих пор, скромна, если не сказать больше.
Спасибо!
Обновление: я также задал вопрос на форумах msdn здесь и получил некоторую подсказку об использовании Measure(), Arrange и updatelayout() перед экспортом в xps. К сожалению, это решение, похоже, не работает. Я думаю, что это было бы далеко, учитывая, что элементы textblock и textbox ведут себя как положено, и у меня есть только проблемы с флажками.
И я решил сделать небольшой проект, который показывает ошибку, чтобы вы также могли немного поэкспериментировать самостоятельно. Вы можете найти это здесь.
Дайте мне знать, если вы что-нибудь выясните:D
2 ответа
Я нашел проблему, и я также нашел начало решения.
Видимо включенные флажки не проверяются при экспорте в wpf. Я предполагаю, что идея разработчиков, когда они писали код, состоит в том, что включенные флажки на листе бумаги должны проверяться только вручную. К сожалению для меня, я хочу проверить их программно.
Я также нашел какое-то решение этой проблемы. Отключенные флажки отображаются как отмеченные и не отмеченные. С основным недостатком, конечно, то, что они все серые, как будто отключенные флажки должны выглядеть.
Ну... я думаю, пришло время выяснить, как изменить стиль моих отключенных флажков, чтобы они выглядели так, как будто они включены. Хммм.... может быть, печатать пять из них друг на друга? Скрещенные пальцы!
Та же проблема происходит с RadioButtons. Я решил это, отобразив свой FixedDocument в окне PrintPreview перед печатью (используя DocumentViewer) (ссылка: http://www.nbdtech.com/Blog/archive/2009/07/09/wpf-printing-part-4-ndash-print-preview.aspx).
РЕДАКТИРОВАТЬ: Возвращаясь к этому вопросу почти через полгода. Требования к моему приложению изменились, и мне пришлось реализовать тихую печать, которая больше не позволяла мне использовать обходной путь окна PrintPreview, упомянутый выше. Решение оказалось похожим на то, что упоминалось в другом ответе. Я закончил тем, что добавил собственный флажок / шаблон переключателя и отключил триггеры в стиле IsEnabled. Проблема в том, чтобы найти шаблон Aero BulletChrome. Следующий вопрос помог в этом отношении /questions/42520276/stilizatsiya-neopredelennogo-sostoyaniya-flazhka-wpf/42520280#42520280