What is the proper way binding from XAML to the Model in ArcGIS Pro SDK framework

2095
10
Jump to solution
11-09-2020 05:50 PM
Amadeus111
Occasional Contributor II

I am able to access properties of an XAML control items directly. For instance, changing a header of a tab in  a Dockpane

XAML (View):

<TabControl x:Name="FavoritesTabs" HorizontalAlignment="Stretch" Height="23" Initialized="FavoritesTabs_Initialized" Margin="8,0,7,0" >
<TabItem x:Name="Tab1" Height="20" Width="75"> </TabItem>
 <TabItem x:Name="Tab2" Height="20" Width="75"></TabItem>
</TabControl>

C# (Model):

private void FavoritesTabs_Initialized(object sender, EventArgs e)
{
    Tab1.Header = "MyFavoriteTab";
}

However, I know it this is not right/proper way and I would like to use MVVM. I would like to bind tab Headers to Model by using MVVM. How can I achieve that?

I think XAML would be 

XAML:

<TabControl x:Name="FavoritesTabs" HorizontalAlignment="Stretch" Height="23" Initialized="FavoritesTabs_Initialized" Margin="8,0,7,0" >
<TabItem x:Name="Tab1" Header="{Binding MyFavorite1}" Height="20" Width="75"> </TabItem>
 <TabItem x:Name="Tab2" Header="{Binding MyFavorite2}" Height="20" Width="75"></TabItem>
</TabControl>


What else I should add Dockpane1ViewModel.cs (View Model) and Dockpane1.xaml.cs (Model)?

0 Kudos
1 Solution

Accepted Solutions
GintautasKmieliauskas
Regular Contributor

Hi,

It is long discussion about about MVVM, pure MVVM and etc, You can find more information on web.

In pure MVVM xxx..xaml.cs should contain only code for setting a page's data context. 

Dockpane.xaml and Dockpane.xaml.cs both comprise View in MVVM? To simplify things I could say "Yes"

If I need to do any changes on the observable collection, I should do it in DockpaneViewModel.cs, right? Yes. Your observable collection must contain items which implement INotifyPropertyChanged. To get selection you need to bind SelectItem to view model property and etc.

As I said in previous reply all what you need to do is edit Dockpane.xaml  using designer and code in 

DockpaneViewModel.cs . Remember about Dockpane.xaml.cs only when you want to rename your classes.

More info on youtube

ArcGIS Pro SDK for .NET: UI Design and MVVM:

https://www.youtube.com/watch?v=5PgaeZycWXc 

View solution in original post

0 Kudos
10 Replies
GintautasKmieliauskas
Regular Contributor

Hi,

You can create new Dockpane from Visual Studio ArcGIS templates and you will see how Dockpane headers are binded. Main header is specified in config.daml file as 'caption' value:

<dockPane id="MyDockpaneID" caption="My Dockpane".

Second one header binding property will be created in dockpane mvvm file:


/// <summary>
/// Text shown near the top of the DockPane.
/// </summary>
private string _heading = "MyFavoritTab";
public string Heading
{
get { return _heading; }
set
{
SetProperty(ref _heading, value, () => Heading);
}
}

In xaml:

<DockPanel Grid.Row="0" LastChildFill="true"
KeyboardNavigation.TabNavigation="Local" Height="30">
<TextBlock Grid.Column="1" Text="{Binding Heading}"
Style="{DynamicResource Esri_TextBlockDockPaneHeader}">

 

 

0 Kudos
Amadeus111
Occasional Contributor II

Thank you @GintautasKmieliauskas  I will check it out As soon as I get time. 

0 Kudos
Amadeus111
Occasional Contributor II

Ok, inside which file I will create private and public headings (Heading and _heading) and how I will access to those headings from the model (Dockpane.xaml.cs) to modify a tab's heading property? 

0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi,

In MVVM you do not need to access xaml controls from View class (.xaml.cs) except some special cases. To do that you need to assign name to  control in xaml with "x:Name".

I would recommend to open one of Esri samples from github with Dockpane and study with debugger how it works.

https://github.com/Esri/arcgis-pro-sdk-community-samples/blob/master/Framework/DockpaneSimple

https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Framework/DockPaneBookmarkAdvan... 

More about dockpanes:

https://github.com/esri/arcgis-pro-sdk/wiki/ProGuide-Dockpanes 

Amadeus111
Occasional Contributor II

@GintautasKmieliauskas  Thank you for your answer. I already saw many examples and read some articles about MVVM but I still have not understood completely. As you said I name the controls via "x:Name" and access them through Dockpane.xaml.cs (I just figured out that this file also part of the view in MVVM) and I know how controls work. I already built a functional dockpane but I would like to organize it in a proper MVVM pattern. 

Dockpane.xaml and Dockpane.xaml.cs both comprise View in MVVM? Dockpane.xaml takes care of Visual elements in UI whereas Dockpane.xaml.cs takes care of events user clicks/selections, initializations etc. 

DockpaneViewModel.cs binds sources to the view. For example, an observable collection points to a listbox as items source. If I need to do any changes on the observable collection, I should do it in DockpaneViewModel.cs, right?

Now, why I need a model then and which one is model file or class in a dockpane module? 

 

0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi,

It is long discussion about about MVVM, pure MVVM and etc, You can find more information on web.

In pure MVVM xxx..xaml.cs should contain only code for setting a page's data context. 

Dockpane.xaml and Dockpane.xaml.cs both comprise View in MVVM? To simplify things I could say "Yes"

If I need to do any changes on the observable collection, I should do it in DockpaneViewModel.cs, right? Yes. Your observable collection must contain items which implement INotifyPropertyChanged. To get selection you need to bind SelectItem to view model property and etc.

As I said in previous reply all what you need to do is edit Dockpane.xaml  using designer and code in 

DockpaneViewModel.cs . Remember about Dockpane.xaml.cs only when you want to rename your classes.

More info on youtube

ArcGIS Pro SDK for .NET: UI Design and MVVM:

https://www.youtube.com/watch?v=5PgaeZycWXc 

0 Kudos
Amadeus111
Occasional Contributor II

Finally, I am beginning to digest MVVM for ArcGIS Pro framework. I think I checked too many examples so MVVM it got confusing. 

I thought It was so easy to use controls from Dockpane.xaml.cs. I guess also Visual Studio is not designed for MVVM well. I can create an event name on Properties Window for a control. Its method shows up in Dockpane.xaml.cs. 

Dockpane.xaml

 

<ListBox x:Name="CountiesListBox" Width="100" Height="200" Margin="0" HorizontalAlignment="Left" Initialized="ListBox_Initialized"

 

Dockpane.xaml.cs

 

 

 

 

 private void ListBox_Initialized(object sender, EventArgs e)
{
    // (Inner voice) Should I do something here?
}

 

 

 

 

Anyway, thanks a lot for your patience and being responsive. It is what is. 

 

 

 

 

0 Kudos
GintautasKmieliauskas
Regular Contributor

Hi,

You can use MVVM only in that cases where Esri UI elements need it ( Dockpanes, PropertyPages and etc.)

All other functionality you can code without MVVM. You can use and windows forms but they look different.

About ListBox_Initialized. Sorry, I have never used this event and I don't  know case where it would be needed.

0 Kudos
Amadeus111
Occasional Contributor II

I started to develop a new module and able to fire up my first binding instead of accessing from Dockpane.xaml.cs. I used the initialization event because I was trying to make a list box's items source ready when Dockpane started even before a user interact with the dockpane. I read the items from a CVS file and add to an Observable collection for the list box. I am sure there is a MVVM way to do this. Thanks again for all your help. 

0 Kudos