2

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.

Simon Fox
  • 10,409
  • 7
  • 60
  • 81

3 Answers3

1

A similar question is asked here with a solution. http://social.msdn.microsoft.com/Forums/en/wpf/thread/67b618aa-f62e-43f8-966c-48057f4d4e0c

JLaanstra
  • 128
  • 6
1

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.

Anvaka
  • 15,658
  • 2
  • 47
  • 56
  • Thank for feedback, solution can be subscribe TextChanged in code behind of user control and if text changed and user is not scrolling richTextBox only class ScrollToEnd. This is mz first big WPF app, I use caliburn micro framewrok, maybe you know it. So I try implement strict MVVM design, but for me is not possible now yet. I check your profile, you are from Ukraine? I am from Slovak republic. –  Feb 10 '11 at 19:08
0

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.

Community
  • 1
  • 1
Simon Fox
  • 10,409
  • 7
  • 60
  • 81