S
S
sergeyfk2017-12-03 11:18:33
JavaScript
sergeyfk, 2017-12-03 11:18:33

How to access control from VM?

How it is possible to address by name to kontrol from VM?
I'm trying to make a command call when the control is initialized and pass the control to the command, but for this, as I understand it, you need to specify the necessary CommandParamers, but which ones?
Or is there a more elegant solution, codeBehind is discouraged.

<intr:Interaction.Triggers>
                    <intr:EventTrigger EventName="Initialized">
                        <intr:InvokeCommandAction Command="{Binding command_InitializedTextBox}"/>
                    </intr:EventTrigger>
                </intr:Interaction.Triggers>

Note: Due to the fact that the textbox contains large text and is frequently updated. Through a simple binding of the Text field, the textbox updates it for a long time. I would like to try a solution like this:
textbox.Append("string");

Answer the question

In order to leave comments, you need to log in

4 answer(s)
P
profesor08, 2019-09-19
@profesor08

Keywords for Google: lazy loading js
Browsers can support lazy loading, read here for familiarization, there are examples and chewed: https://web.dev/native-lazy-loading
For the same pictures, you can set some background, but for loading articles via ajax, you will have to be confused by creating a stub in the form of beautiful empty lines, as in your screenshot, which will be replaced as soon as the necessary data is loaded.

X
xmoonlight, 2019-09-18
@xmoonlight

1. lazyload
2. includeHTML .

I
Ihor Bratukh, 2019-09-18
@BRAGA96

Skeleton loading + ajax

S
sergeyfk, 2017-12-03
@sergeyfk

I still wrote my crutch, which works quite well, but not perfectly. Now I'll tell you everything in brief...
Let's start with a helper class for calling commands:

public class ActionCommand : ICommand
    {
        private Action _action;
        private Action<object> _actionObj;
        public ActionCommand(Action action)
        {
            _action = action;
        }
        public ActionCommand(Action<object> actionObj)
        {
            _actionObj = actionObj;
        }
        public bool CanExecute(object parameter)
        {
            return true;
        }
        public void Execute(object parameter)
        {
            if (parameter == null)
            {
                _action?.Invoke();
            }
            else if (parameter is System.Windows.Controls.TextBox)
            {
                _actionObj?.Invoke(parameter);
            }
        }
        public event EventHandler CanExecuteChanged;
    }

I don't think there's anything to explain here. There are enough descriptions of such classes. I just added an Action with a parameter and checking the parameter for null and the type of the object I need.
Let's move on...
We need to add the following parameter to the Window tag and add the corresponding library, which is in nuget
Let's create our control:
<TextBox Text="{Binding Log, Mode=OneWay}" IsReadOnly="True" Margin="5" VerticalScrollBarVisibility="Auto" HorizontalScrollBarVisibility="Auto">
                <intr:Interaction.Triggers>
                    <intr:EventTrigger EventName="TextChanged">
                        <intr:InvokeCommandAction Command="{Binding command_InitializedTextBox}" 
                                                  CommandParameter="{Binding RelativeSource=
                                                 {RelativeSource
                                                 Mode=FindAncestor,
                                                 AncestorType=TextBox}}"/>
                    </intr:EventTrigger>
                </intr:Interaction.Triggers>
            </TextBox>

I draw attention to AncestorType=TextBox. You need to change the value to what you need (as in the helper class), otherwise the found TextBox will be passed, if it exists at all. I immediately answer the expected questions:
using the Loaded and Initialized events will not work in this case, because The VM is declared later than these events fire.
Well, let's go to the cluster of crutches ... In the ViewModel
public ICommand command_InitializedTextBox
        {
            get
            {
                return new ActionCommand((object sender) => { InitializedTextBox(sender); });
            }
        }
        private void InitializedTextBox(object sender)
        {
            _LogControl = ((System.Windows.Controls.TextBox)sender);
        }

Everything should be clear here.
And here is void for adding text.
private void AppendLogText(string getter)
        {
            if (_LogControl != null)
            {
                _LogControl.AppendText(getter);
            }
            else
            {
                Log += getter;
            }
        }

The text is changed by binding only once.
I want to note that this solution is worth using when large texts are used. TextBox "thinks" for a long time when using large texts and bindings, but not when using AppendText.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question