There is a UserControl . I want to use it in two projects. There is such an idea: in UserControl to lay all the functionality that can be accessed, and in the application, simply bind to the interface elements. As I see it, you probably have to use commands. Tell me how best to implement this? Examples that I found on the web are usually considered existing WPF commands.

UPD: There is a UserControl on which ListBox is located to display the list of cars from the database. In this UserControl I want to add add / remove machine commands. These commands will execute the stored procedure from the database. On the main form of the application, I place the buttons and my UserControl . I want to bind the commands from the UserControl to the buttons. Those. in the application itself, I no longer register the execution of stored procedures, this is all already in UserContorol

  • those. (with reference to the example) binding and working with the database is implemented in the control, and in the code that uses your control do you go on a command to make a call to a method implemented in the control that performs a call to the storage, etc.? - Alexey
  • exactly. corrected primerchik. - MaximK
  • one
    In general, the practice is usually reversed - the control only displays, and how the view model decides how to receive and change data. Otherwise, your control is too much attached to the project and reuse will not work. - Monk

2 answers 2

Let's try to show an example

 public partial class MyUserControl : UserControl { ... public ICommand MyCommand { get { return (ICommand)GetValue(MyCommandProperty); } set { SetValue(MyCommandProperty, value); } } public static readonly DependencyProperty MyCommandProperty = DependencyProperty.Register("MyCommand", typeof(ICommand), typeof(MyUserControl)); ... } 

Here we in our control declared the command, and what we described it as DependencyProperty will give us the opportunity to bind the command from the ViewModel to it, for example.

Now at the right moment we need to run it. Let this moment be the loading event of the control. We add to the code above

 private void MyUserControl_Loaded(object sender, RoutedEventArgs e) { MyCommand?.Execute(/*Тут указывается параметр для команды, можно null*/); } 

On the control side, we are done. Now we will connect our team with real action. In the ViewModel we describe a command that simply displays a MessageBox . As an ICommand implementation, I most often use the RelayCommand from MvvmLight .

 public RelayCommand ShowMessageCommand { get; private set; } private void ShowMessage() { MessageBox.Show("Hello!"); } 

And in the constructor ViewModel initialize

ShowMessageCommand = new RelayCommand (ShowMessage);

Now, for example, in the window, in which DataContext an instance of our ViewModel is installed we describe the following

 <local:MyUserControl ... MyCommand={Binding Path=ShowMessageCommand}/> 

Now when you call MyCommand?.Execute function will be ShowMessage . To complete the picture is not enough use of the parameters. But there is nothing difficult there. If you still do not understand yourself - ask.

UPDATE

In order for the control to bind a button to MyCommand , simply bind the Button.Command property to MyCommand . Thus, when you click on the button, the necessary command will be executed. But to do so

 Т.е. в самом приложении, я уже не прописываю выполнение хранимых процедур, это все уже есть в UserContorol 

Absolutely wrong. Controls should not take on such functionality

  • It seems that I have an inverse problem. On the UserControl side, I need ShowMessage , and on the application side, I only need to call it when I press the button - MaximK
  • You wrote that> For example: There is a UserControl on which the DataGrid is tied to the database and receiving information from there. To add data, I call the stored procedure. So, how to place this challenge in a team? Or maybe there are other ways. How did you implement these solutions? <Duck, the procedure call should not occur in control, this task is just the same ViewModel - Donil
  • slightly corrected the example of what I need - MaximK
  • And if you do not use MvvmLight - MaximK
  • WPF has its own ICommand implementations. RoutedUICommand , for example. stackoverflow.com/questions/1468791/… - implemented it yourself - Donil

In addition to the answer @Donil (with which I fully agree):

See it. UI should not be engaged in any "activity", especially addressing the database. The correct design should be:

  1. You have an ObservableCollection<CarVM> in your VM and both AddCar and RemoveCar .
  2. The collection should keep the list of machines up to date, the AddCar and RemoveCar should start asynchronously updating the database with the model and then probably update the list of machines. Communicating with the base is a model-level question, while the task of maintaining the list in the correct state is a question for the VM.
  3. The control should pry the collection as ItemsSource into its ListBox , and set the buttons (or something similar), which have commands from the VM to the Command property.

Everything.