2016-08-25 28 views
0

我已经设置为维护一个wpf应用程序,其中有一个用于记录目的的列表框。从Datatemplate触发器的代码获取绑定表达式

使用列表框的项是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; } 
} 

的ListBox中的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,我真的很感激,如果有人有解决这个小费。 (我试过很难找到在这里计算器的解决方案,但到目前为止,我一直不成功)提前

感谢,

王认为 马格努斯

+0

啊...只是指出一个解决办法是冒险下来 路径'listBox.ItemTemplate.Triggers' – Metscore

回答

0

请与内容设置为一个ContentPresenter你的TextMessage。将ContentTemplate设置为listBox.ItemTemplate并应用该模板。它将创建视觉效果(在这种情况下为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(); 
} 
+0

我应该提到的是,我从HTTP RichTextBox的代码:// stackoverflow.com/questions/5512921/wpf-richtextbox-appending-coloured-text –