我正在开发一些专门的日志查看器,其中我在列表视图中显示日志条目列表。
该应用程序由一个 Window 组成(实际上,使用Catel,所以它是一个 DataWindow ),其中我有 UI。由于我使用的是 MVVM,因此我还创建了相应的 VM。我的模型是具有 LogEntrys 集合的日志。日志在用户交互时加载到 VM 中。
每个 LogEntry 都有一个 Message 属性,它是一些我想解析为 XAML 并将其部分转换为超链接的文本(字符串属性)。当用户单击超链接时,我想执行一些在主 VM 中定义的命令(必须在那里,因为它使用了一些属于 VM 的属性)。
最初我尝试使用 RichTextBox。由于 WPF 不支持绑定,因此我决定使用 Extended WPF Toolbox(此处)中的 RTB。
我创建了一个自定义ITextFormatter
,它读取文本并构建一个FlowDocument
(注意在ITextFormatter
(FlowDocument
文档参数)中传入)。在SetText
:
foreach (var line in text.Split('\n'))
{
//some manipulations
Paragraph para = new Paragraph();
para.Inlines.Add(new Run(manipulatedText1));
para.Inlines.Add(CreateHyperLink(manipulatedText2));
document.Blocks.Add(para);
}
该CreateHyperLink
函数应该构建Hyperlink
并设置它的命令和参数:
private Hyperlink CreateHyperlink(string text)
{
var hLink = new Hyperlink(new Bold(new Run(text)));
hLink.TargetName = text;
//Attach a command and set arguments (target etc)
hLink.Command = ???
hLink.TargetName = text;
//Do some formatting
return hLink;
}
这使我进入了一个阶段,我在 RTB 中看到了我的格式化内容,ListView
但它们只是带下划线,表现为常规文本并且没有任何操作。(在这里发布了问题,但还没有答案)。
然后,当我试图找到解决方案时,我偶然发现了FlowDocumentScrollViewer
. 我创建了一个IValueConverter
解析文本(消息)并使用超链接构建文档的文件。这似乎是一个稍微简单和更清洁的解决方案。使用这种方法,我得到了格式化的消息显示,并且超链接被识别为这样(以蓝色显示并作为一个“整体”单元出现),但仍然无法让命令触发。
因此我有两个问题:
哪个控件是更好的选择,或者使用每个控件的优缺点是什么?
FlowDocumentScrollViewer
本质上是只读的,并且可能支持更好的格式(?),但它确实给ListView
用鼠标滚动时带来了一些问题(当超过 a 时FlowDocumentScrollViewer
,它不会滚动列表,也许可以修复)如何将命令从 VM 传递到超链接并让它执行?我认为应该进行一些绑定,但不确定如何/在哪里。在渲染 FlowDocument 时,我尝试在两者中创建
ITextFormatter
并IValueConverter
使用ICommand
DependancyProperty
它的值,但要么它不合法(因为实例是作为静态资源创建的),要么我没有正确绑定它
我试过(在):
<local:TextToFlowDocumentConverter
x:Key="textToFlowDocumentConverter"
HyperlinkCommand="{Binding NavigateDnHyperlinkCommand,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type catel:DataWindow}}, Path=DataContext}"/>
我想我可以在 VM 上实例化格式化程序/转换器,但这不是正确的 MVVM ...
顺便说一句,我也尝试在解析时“硬编码”链接(CreateHyperLink
上面)
hLink.RequestNavigate += new System.Windows.Navigation.RequestNavigateEventHandler(hLink_RequestNavigate);
这对两个控件都不起作用
另外,我在 XAML 中设置了Hyperlink.Click
and Hyperlink.RequestNavigate
(附加属性(?))并将它们放在后面的 Window 代码中 - 这确实有效(注意:在 RTB 的情况下,您必须设置IsDocumentEnabled="True"
and IsReadOnly="True"
!)
谢谢,
托默