简体   繁体   中英

What is the best practice for opening a new dialog inside a user control inside a window?

Problem

I have a main window with multiple Menu Items on the left hand side acting as a navigation bar. Menu items open different user control on the main window. Here is an example of one user control.

  • A data-grid view where a user is able to select a single record.
  • That selected item can be deleted from the database by click of a button. (Not a problem, because I can hook this to a ViewModel where the command is held to delete the record.
  • That selected item can be updated on click of a button. New screen shows up with the textboxes already filled with data we selected. (My main concern).

Current Code

View: FSQMView.xaml

Here is an example of a view, as you can see I have a DataGrid, it loads records from FSQMRecords with a single column called DocumentReference .

<DataGrid x:Name="FSQMGrid" 
          ItemsSource="{Binding FSQMRecords}"
          IsReadOnly="True"
          AutoGenerateColumns="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding DocumentReference}" Header="Document Reference"/>
    </DataGrid.Columns>
</DataGrid>

View.cs: FSQMView.xaml.cs

This might be a bad practise because to me it seems like I am going against the MVVM pattern.

Here I am passing the SelectedItem from the DataGrid to the new window.

private void UpdateButton_Click(object sender, RoutedEventArgs e)
{
    FSQMUpdate window = new FSQMUpdate()
    {
        DataContext = FSQMGrid.SelectedItem
    };

    window.ShowDialog();
}

View: FSQMUpdate.xaml

In the new window, I am receiving the data and display it in the textbox. Also, I would have another 2 buttons where I can update the record and click cancel to exit the screen.

<TextBox Text="{Binding DocumentReference, Mode=OneTime}"/>

<Button Command="{Binding UpdateCommand}"
        Click="Update"/>
<Button Command="{Binding CancelCommand}"
        Click="Cancel Edit"/>

Question

Would this be the correct way of loading a dialog inside a user control?

Sounds like a simple master/detail view. I would probably bind a list of view models to a ListBox on the left. Then render selected view model's content property on the right with a content presenter using a DataTemplate. Your view models must have a property called "Content" in this example.

<DockPanel>
  <ListBox ItemsSource="{Binding Path=YourItems}"
           SelectedItem="{Binding Path=YourSelectedItem}" 
           DockPanel.DockLeft/>
  <ContentPresenter Content="{Binding Path=YourSelectedItem.Content}"/>
</Dockpanel>

(ListBox also has an ItemTemplate that can be used to change the way your items look on the left)

Inside your selected view model you can do pretty much the same. Think of it like a hierarchical data structure. Simply bind the DataGrid's selected item to a property in your view model. Also have a look at DataGrid's properties "SelectionUnit" and "SelectionMode".

<DataGrid SelectedItem="{Binding Path=SelectedItemProperty}">

</DataGrid>

Using DataBinding allows you to get rid of all those EventHandlers in your view model. For more interaction bewteen view model and view you can look at ICommand implementations like RelayCommand. It's straight forward and easy to use.

Note: For everything that needs to be updated, have a look at the INotifyPropertyChanged interface if you want to update your UI on data changes caused by your view model. It's very well known an can be found easily.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM