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