从Datatemplate Triggers后面的代码中获取绑定表达式
本文关键字:获取 绑定 表达式 代码 Datatemplate Triggers | 更新日期: 2023-09-27 18:03:59
我被设置为维护一个wpf应用程序,其中有一个用于日志记录的列表框。
使用列表框显示的项目类型为TextMessage
,即列表框通过
ObservableCollection<TextMessage> Messages;
listBox.DataContext = Messages;
消息然后添加类似
的内容 Messages.Add(new TextMessage("Test", TypeOfMessage.Headline));
这是TextMessage
类的定义
public enum TypeOfMessage
{
Normal,
Headline,
Focus,
Important,
Fail,
Success
}
public class TextMessage
{
public TextMessage(string content, TypeOfMessage typeOfMessage)
{
Content = content;
TypeOfMessage = typeOfMessage;
CreationTime = DateTime.Now;
}
public string Content { get; }
public TypeOfMessage TypeOfMessage { get; }
public DateTime CreationTime { get; }
}
列表框的xaml定义如下:
<ListBox x:Name="listBox" HorizontalAlignment="Left" Height="196" Margin="101,77,0,0" VerticalAlignment="Top" Width="256" ItemsSource="{Binding}" SelectionMode="Multiple">
<ListBox.InputBindings>
<KeyBinding
Key="C"
Modifiers="Control"
Command="Copy"
/>
</ListBox.InputBindings>
<ListBox.CommandBindings>
<CommandBinding
Command="Copy"
Executed="DoPerformCopy"
/>
</ListBox.CommandBindings>
<ListBox.ItemTemplate>
<DataTemplate>
<TextBlock x:Name="TextToShow" Text="{Binding Content}"></TextBlock>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Normal">
<Setter TargetName="TextToShow" Property="Foreground" Value="Black"/>
</DataTrigger>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Focus">
<Setter TargetName="TextToShow" Property="Foreground" Value="Black"/>
<Setter TargetName="TextToShow" Property="FontWeight" Value="Bold"/>
</DataTrigger>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Headline">
<Setter TargetName="TextToShow" Property="Foreground" Value="RoyalBlue"/>
<Setter TargetName="TextToShow" Property="FontWeight" Value="Bold"/>
</DataTrigger>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Important">
<Setter TargetName="TextToShow" Property="Foreground" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Fail">
<Setter TargetName="TextToShow" Property="Foreground" Value="Red"/>
<Setter TargetName="TextToShow" Property="FontWeight" Value="Bold"/>
</DataTrigger>
<DataTrigger Binding="{Binding TypeOfMessage}" Value="Success">
<Setter TargetName="TextToShow" Property="Foreground" Value="Green"/>
<Setter TargetName="TextToShow" Property="FontWeight" Value="Bold"/>
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
这工作得很好(即消息显示在列表框中不同的字体粗细和颜色取决于他们的类型),但现在的问题:
是否有任何方法使用BindingExpression或任何其他方法从xaml定义后面的代码中获得字体格式和着色?
原因是,我只想有格式化在一个地方(只是在xaml,因为它是现在),但仍然能够重用它,当我想复制的内容(使用后面的代码),包括字体格式到剪贴板。
的例子:
private void DoPerformCopy()
{
RichTextBox rtb = new RichTextBox();
foreach (TextMessage message in (listBox as ListBox)?.SelectedItems.Cast<TextMessage>().ToList())
{
TextPointer startPos = rtb.CaretPosition;
rtb.AppendText(message.Content);
rtb.Selection.Select(startPos, rtb.CaretPosition.DocumentEnd);
//
// Here it would be very nice to instead having multiple switch statements to get the formatting for the
// TypeOfMessage from the xaml file.
SolidColorBrush scb = new SolidColorBrush(message.TypeOfMessage == TypeOfMessage.Fail ? Colors.Red);
//
rtb.Selection.ApplyPropertyValue(RichTextBox.ForegroundProperty, scb);
}
// Now copy the whole thing to the Clipboard
rtb.Selection.Select(rtb.Document.ContentStart, rtb.Document.ContentEnd);
rtb.Copy();
}
由于我是wpf的新手,如果有人有解决这个问题的建议,我将非常感激。(我已经努力在stackoverflow上找到解决方案,但到目前为止我还没有成功)
提前感谢,
国王的问候马格努斯
创建一个内容设置为TextMessage的ContentPresenter。设置ContentTemplate为listBox。并应用该模板。它将创建视觉效果(在本例中为TextBlock)。然后,只需解析来自TextBlock的值。
另外,你的RichTextBox选择代码不太正确,所以我通过插入TextRanges到它的末尾,而不是试图得到正确的选择来修复这一点。
private void DoPerformCopy(object sender, EventArgs e)
{
RichTextBox rtb = new RichTextBox();
foreach (TextMessage message in (listBox as ListBox)?.SelectedItems.Cast<TextMessage>().ToList())
{
ContentPresenter cp = new ContentPresenter();
cp.Content = message;
cp.ContentTemplate = listBox.ItemTemplate;
cp.ApplyTemplate();
var tb = VisualTreeHelper.GetChild(cp, 0) as TextBlock;
var fg = tb.Foreground;
var fw = tb.FontWeight;
var tr = new TextRange(rtb.Document.ContentEnd, rtb.Document.ContentEnd);
tr.Text = message.Content;
tr.ApplyPropertyValue(RichTextBox.ForegroundProperty, fg);
tr.ApplyPropertyValue(RichTextBox.FontWeightProperty, fw);
}
// Now copy the whole thing to the Clipboard
rtb.Selection.Select(rtb.Document.ContentStart, rtb.Document.ContentEnd);
rtb.Copy();
}