从 View Model 类调用 RichTextBox.ScrollToEnd()

发布于 2024-10-16 13:58:03 字数 225 浏览 2 评论 0原文

您好,我尝试解决这个问题,在 WPF 中我使用 Caliburn Micro 框架。在视图中,我有可绑定的 Richtextbox 控件,我从 FlowDocument 的视图模型类属性类型进行绑定。

我需要一种方法,如何在视图中的 richetextbox 控件上调用 ScrollToEnd 方法。

是否可以?因为在视图模型类中我没有 richtextbox 的实例。

谢谢你的主意。

Hi I try solve this, in WPF I use Caliburn Micro framework. In View I have bindable richtextbox control, I bind from view model class property type of FlowDocument.

I need have a way how can I call method ScrollToEnd on richetextbox control in view.

Is it possible? Because in view model class I don’t have instance of richtextbox.

Thank for idead.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

迷途知返 2024-10-23 13:58:03

有时,从代码隐藏文件中调用 UI 代码是有意义的(如果其他解决方案使事情变得复杂)。请记住:模式只是建议而不是脚本。有人甚至可能会争辩说,从视图模型中公开 FlowDocument 会使视图模型过于了解 UI。但你这样做是因为它更容易,对吗?

如果您不想从后面的代码进行此调用,有两种选择:

  • 考虑使用一个 ScrollToEnd() 方法将接口注入视图模型。 View 实现此方法,并且视图模型在需要时调用它。
  • 从视图模型 ScrollToEndRequested 公开事件。 View 订阅此事件并在触发时采取相应的操作。

其他选项(例如附加行为)可能更合适,但它们实际上取决于您的上下文。

Sometimes it makes sense to call UI code from the code behind file (if other solutions complicate things). Remember: patterns are just recommendations not the script. One could even argue that exposing a FlowDocument from view model makes the view model too aware about UI. But you did it because it was easier, right?

If you don't want to make this call from code behind, here are two options:

  • Consider injecting an interface to the view model, with one ScrollToEnd() method. View implements this method and view model calls it whenever it feels necessity.
  • Expose an event from view model ScrollToEndRequested. View subscribes to this event and acts accordingly whenever it's fired.

Other options (like attached behaviors) might be more suitable, but they are really depend on your context.

雅心素梦 2024-10-23 13:58:03

我提供了有关使用 Caliburns IResult 将焦点设置为特定控件的问题的答案 此处。您应该能够使用相同的概念来获取 RichTextBox 以便调用 ScrollToEnd。我不会在这里重复整个解释,请转到该问题以获取想法,但以下 IResult 实现(作为指南)应该会让您走上正确的轨道。

public class RichTextBoxScrollToEnd : ResultBase
{
    public RichTextBoxScrollToEnd()
    {

    }

    public override void Execute(ActionExecutionContext context)
    {
        var view = context.View as UserControl;

        List<Control> richTextBoxes =
            view.GetChildrenByType<Control>(c => c is RichTextBox);

        var richTextBox = richTextBoxes.FirstOrDefault();

        if (richTextBox != null)
            richTextBox.Dispatcher.BeginInvoke(() =>
        {
            richTextBox.ScrollToEnd();
        });

        RaiseCompletedEvent();
    }
}

如果您的视图中有多个 RichTextBox,您可以向 RichTextBoxScrollToEnd 的构造函数提供一个参数,它是您要定位的特定控件的名称,然后使用该参数过滤 richTextBox name ie

var richTextBox = richTextBoxes.FirstOrDefault(c => c.Name == _nameOfControl);

不过,请参阅引用的问题以获取更多详细信息。

I provided an answer to a question about setting the focus to a specific control using Caliburns IResult here. You should be able to use the same concept to get hold of the RichTextBox in order to invoke ScrollToEnd. I will not duplicate the entire explanation here, go to that question for the ideas, but the following IResult implementation (as a guide) should put you on the right track.

public class RichTextBoxScrollToEnd : ResultBase
{
    public RichTextBoxScrollToEnd()
    {

    }

    public override void Execute(ActionExecutionContext context)
    {
        var view = context.View as UserControl;

        List<Control> richTextBoxes =
            view.GetChildrenByType<Control>(c => c is RichTextBox);

        var richTextBox = richTextBoxes.FirstOrDefault();

        if (richTextBox != null)
            richTextBox.Dispatcher.BeginInvoke(() =>
        {
            richTextBox.ScrollToEnd();
        });

        RaiseCompletedEvent();
    }
}

If you have multiple RichTextBoxes in your view you could provide a parameter to the constructor of RichTextBoxScrollToEnd which is the name of the specific control you want to target and then filter richTextBoxes using that name i.e.

var richTextBox = richTextBoxes.FirstOrDefault(c => c.Name == _nameOfControl);

See the referenced question for more details though.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文