我有一个带有RichEditBox(编辑器)和Grid(MarginNotes)的Windows应用商店应用程序.
我需要始终匹配两个元素的垂直滚动位置.这样做的目的是允许用户在文档的边缘添加注释.
我已经根据光标位置找出了Note定位 - 当添加一个音符时,将对光标之外的所有内容进行文本选择.然后将该选择添加到第二个不可见的RichEditBox内部StackPanel.然后我得到了ActualHeight这个控件,它给出了网格中音符的位置.
我的问题是,当我RichEditBox向上和向下滚动时,Grid不会相应地滚动.
第一种技术
我尝试将它们都放在一个内部ScrollViewer,并禁用滚动RichEditBox
<ScrollViewer x:Name="EditorScroller"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="{Binding *" />
<ColumnDefinition Width="150" />
</Grid.ColumnDefinitions>
<Grid x:Name="MarginNotes" Grid.Column="0" HorizontalAlignment="Right"
Height="{Binding ActualHeight, ElementName=editor}">
</Grid>
<StackPanel Grid.Column="1">
<RichEditBox x:Name="margin_helper" Opacity="0" Height="Auto"></RichEditBox>
</StackPanel>
<RichEditBox x:Name="editor" Grid.Column="1" Height="Auto"
ScrollViewer.VerticalScrollBarVisibility="Hidden" />
</Grid>
</ScrollViewer>
Run Code Online (Sandbox Code Playgroud)
当我滚动到RichEditBox控件的底部,然后按几次输入时,光标就会消失.该ScrollViewer不会自动用光标滚动.
我尝试添加C#代码,它将检查光标的位置,将其VerticalOffset与编辑器的高度进行比较,然后相应地调整滚动.这很有效,但速度非常慢.最初,我在KeyUp活动中使用它,当我输入一个句子时,应用程序停止了.然后我把它放在一个5秒的计时器上,但这仍然减慢了应用程序的性能,也意味着光标在视线和RichEditBox滚动之间可能会有5秒的延迟.
第二种技术
我也试过把MarginNotes …
textbox scrollviewer richedit-control winrt-xaml windows-store-apps
我试图将从richeditDocument生成的内存流转换为字节数组.代码如下:
Public Sub saveAsTemplate_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim ms As MemoryStream = New MemoryStream()
richEditControl1.SaveDocument(ms, DocumentFormat.Rtf)
GetStreamAsByteArray(ms)
MessageBox.Show("save")
End Sub
Private Function GetStreamAsByteArray(ByVal stream As MemoryStream) As Byte()
Dim streamLength As Integer = Convert.ToInt32(stream.Length)
Dim fileData As Byte() = New Byte(streamLength) {}
' Read the file into a byte array
stream.Read(fileData, 0, streamLength)
stream.Flush()
stream.Close()
Return fileData
End Function
Run Code Online (Sandbox Code Playgroud)
生成流时我可以获得流长度,但最终的咬合数组只包含0,使其无效.我怎样才能获得正确的字节数组?
假设您刚刚在启用拼写检查的丰富编辑控件中设置了一些文本,并且该文本存在一些拼写错误。一瞬间过去了,拼写检查将启动,然后拼写错误的文本将带有下划线。但猜猜看:丰富的编辑控件实际上EN_CHANGE只会针对下划线事件发送通知(假设您已通过执行以下操作注册了通知SendMessage(hwnd, EM_SETEVENTMASK, 0, (LPARAM)ENM_CHANGE))。
有没有解决方法可以避免这种行为?我有一个对话框,其中包含一些启用拼写检查的丰富编辑控件。我还想知道编辑事件何时发生,这样我就知道何时启用“保存”按钮。因此,仅获取EN_CHANGE拼写检查下划线事件的通知是一个问题。
我考虑过的一种选择是 EN_CHANGE完全禁用通知,然后在子类化的丰富编辑控件中自行触发它们。例如,当有 a 时WM_CHAR,它会 EN_CHANGE显式发送通知等。但这似乎是一个问题,因为有许多类型的事件应该触发更改,例如删除、复制/粘贴等,我可能会无法正确捕获所有这些。
我考虑过的另一个选择是EN_CHANGE动态启用和禁用通知。例如,仅在有焦点时启用它们,并在焦点被终止时禁用它们。但这似乎也有问题,因为丰富的编辑在设置文本时可能已经具有焦点。然后会出现拼写检查下划线,并且EN_CHANGE会发送不需要的通知。
我想也可以使用计时器,但我认为这很容易出错。
有人还有其他想法吗?
这是一个可重现的示例。只需运行它,它就会说发生了一些变化:
#include <Windows.h>
#include <atlbase.h>
#include <atlwin.h>
#include <atltypes.h>
#include <Richedit.h>
class CMyWindow :
public CWindowImpl<CMyWindow, CWindow, CWinTraits<WS_VISIBLE>>
{
public:
CMyWindow()
{
}
BEGIN_MSG_MAP(CMyWindow)
MESSAGE_HANDLER(WM_CREATE, OnCreate)
COMMAND_CODE_HANDLER(EN_CHANGE, OnChange)
END_MSG_MAP()
private:
LRESULT OnCreate(UINT, WPARAM, LPARAM, BOOL& bHandled)
{
bHandled = FALSE;
LoadLibrary(L"Msftedit.dll");
CRect rc;
GetClientRect(&rc);
m_wndRichEdit.Create(MSFTEDIT_CLASS, m_hWnd, &rc,
NULL, WS_VISIBLE | WS_CHILD | WS_BORDER); …Run Code Online (Sandbox Code Playgroud) atl ×1
bytearray ×1
c++ ×1
richedit ×1
scrollviewer ×1
silverlight ×1
textbox ×1
vb.net ×1
winapi ×1
winrt-xaml ×1