Skip to content

Commit 1494e0f

Browse files
Merge pull request #1237 from telerik/new-kb-radtreedatagrid-binding-selecteditems-viewmodel-70bfdba692f041ce80e2094e4389c88c
Added new kb article radtreedatagrid-binding-selecteditems-viewmodel
2 parents 293ff63 + 8edb260 commit 1494e0f

File tree

1 file changed

+215
-0
lines changed

1 file changed

+215
-0
lines changed
Lines changed: 215 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,215 @@
1+
---
2+
title: Binding TreeDataGrid SelectedItems Collection to ViewModel
3+
description: Explains why SelectedItems in RadTreeDataGrid cannot be bound directly in XAML and shows how to use it in the ViewModel.
4+
type: how-to
5+
page_title: Using SelectedItems in RadTreeDataGrid with ViewModel Binding
6+
meta_title: Using SelectedItems in RadTreeDataGrid with ViewModel Binding
7+
slug: radtreedatagrid-binding-selecteditems-viewmodel
8+
tags: radtreedatagrid, .net maui, selecteditems, binding, xaml, viewmodel
9+
res_type: kb
10+
---
11+
12+
## Environment
13+
14+
| Version | Product | Author |
15+
| --- | --- | ---- |
16+
| 11.1.0 | Telerik UI for .NET MAUI TreeDataGrid | [Dobrinka Yordanova](https://www.telerik.com/blogs/author/dobrinka-yordanova) |
17+
18+
## Description
19+
20+
I need to bind the `SelectedItems` property of [TreeDataGrid](https://docs.telerik.com/devtools/maui/controls/treedatagrid/overview) to a collection property in my `ViewModel`, but I noticed that it is not available for binding in XAML. However, it seems accessible in the code-behind file. Is there a way to bind this collection to the `ViewModel`?
21+
22+
This knowledge base article also answers the following questions:
23+
24+
- Why is `SelectedItems` not available for binding in XAML?
25+
- How can I work with `SelectedItems` in the `ViewModel`?
26+
- How can I use `SelectedItems` with collection updates?
27+
28+
## Solution
29+
30+
The `SelectedItems` property of the TreeDataGrid is a read-only collection with a private setter, which means it cannot be directly bound in XAML. IntelliSense does not suggest properties with private setters for XAML binding, and therefore, two-way binding is not supported.
31+
32+
To use `SelectedItems` in your `ViewModel`, follow these steps:
33+
34+
**1.** Define the TreeDataGrid control:
35+
36+
```XAML
37+
<telerik:RadTreeDataGrid x:Name="treeDataGrid" ItemsSource="{Binding Items}"
38+
SelectedItems="{Binding Selection, Mode=OneWayToSource}"
39+
SelectionMode="Multiple"
40+
AutoGenerateColumns="False">
41+
<telerik:RadTreeDataGrid.ItemDescriptor>
42+
<telerik:TreeDataGridItemDescriptor ItemsSourceBinding="{Binding Children}" />
43+
</telerik:RadTreeDataGrid.ItemDescriptor>
44+
<telerik:RadTreeDataGrid.Columns>
45+
<telerik:DataGridTextColumn PropertyName="Name" />
46+
<telerik:DataGridNumericalColumn PropertyName="Size" />
47+
<telerik:DataGridTextColumn PropertyName="Type" />
48+
</telerik:RadTreeDataGrid.Columns>
49+
</telerik:RadTreeDataGrid>
50+
```
51+
52+
**2.** Define the `ViewModel` and subscribe to the `CollectionChanged` event of the `SelectedItems` property. This event notifies you when the selection changes.
53+
54+
```C#
55+
public class MainPageViewModel : NotifyPropertyChangedBase
56+
{
57+
private ObservableCollection<object> selection;
58+
59+
public MainPageViewModel()
60+
{
61+
Items = new ObservableCollection<Data>();
62+
Items.Add(new Data("My Projects", 234, "Folder")
63+
{
64+
Children = new ObservableCollection<Data>()
65+
{
66+
new Data("Using latest Telerik .NET MAUI controls", 234 ,"Folder")
67+
{
68+
Children = new ObservableCollection<Data>()
69+
{
70+
new Data("TreeDataGrid", 6, "File"),
71+
new Data("CollectionView", 6, "File"),
72+
new Data("DataGrid", 54, "File"),
73+
new Data("Scheduler", 12, "File"),
74+
new Data("TreeView", 2, "File"),
75+
new Data("Calendar", 23, "File"),
76+
new Data("RichTextEditor", 0, "File"),
77+
new Data("PdfViewer", 55, "File"),
78+
new Data("ToggleButton", 21, "File"),
79+
new Data("TemplatedButton", 88, "File"),
80+
}
81+
},
82+
new Data("Blank project", 0, "Folder")
83+
}
84+
});
85+
Items.Add(new Data("Shared Documents", 643, "Folder")
86+
{
87+
Children = new ObservableCollection<Data>()
88+
{
89+
new Data("Reports", 643, "Folder")
90+
{
91+
Children = new ObservableCollection<Data>()
92+
{
93+
new Data("October", 234, "File"),
94+
new Data("November", 0, "File"),
95+
new Data("December", 409, "File")
96+
}
97+
}
98+
}
99+
});
100+
Items.Add(new Data("Pictures", 643, "Folder")
101+
{
102+
Children = new ObservableCollection<Data>()
103+
{
104+
new Data("Camera Roll", 231, "Folder")
105+
{
106+
Children = new ObservableCollection<Data>()
107+
{
108+
new Data("hello.png", 107, "File"),
109+
new Data("happy_summer.png", 0, "File"),
110+
new Data("avatar.png", 124, "File")
111+
}
112+
},
113+
new Data("Saved Pictures", 453, "Folder")
114+
{
115+
Children = new ObservableCollection<Data>()
116+
{
117+
new Data("vacation.png", 234, "File"),
118+
new Data("november.png", 0, "File"),
119+
new Data("mountains.png", 227, "File")
120+
}
121+
}
122+
}
123+
});
124+
Items.Add(new Data("Documents", 876, "Folder")
125+
{
126+
Children = new ObservableCollection<Data>()
127+
{
128+
new Data("Internal Usage Only", 643, "Folder")
129+
{
130+
Children = new ObservableCollection<Data>()
131+
{
132+
new Data("reports.docx", 234, "File"),
133+
new Data("confidential.xlsx", 0, "File"),
134+
new Data("internal_usage.pdf", 409, "File")
135+
}
136+
}
137+
}
138+
});
139+
}
140+
public ObservableCollection<Data> Items { get; set; }
141+
142+
public ObservableCollection<object> Selection
143+
{
144+
get => this.selection;
145+
set
146+
{
147+
if (this.selection != value)
148+
{
149+
if (this.selection != null)
150+
{
151+
this.selection.CollectionChanged -= SelectedItems_CollectionChanged;
152+
}
153+
154+
this.selection = value;
155+
Device.StartTimer(TimeSpan.FromMicroseconds(300), () =>
156+
{
157+
this.selection.Add(this.Items[0]);
158+
return false;
159+
});
160+
161+
this.OnPropertyChanged();
162+
163+
if (this.selection != null)
164+
{
165+
this.selection.CollectionChanged += SelectedItems_CollectionChanged;
166+
}
167+
}
168+
}
169+
}
170+
171+
private void SelectedItems_CollectionChanged(object? sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
172+
{
173+
if (e.Action == NotifyCollectionChangedAction.Add)
174+
{
175+
// add your logic here
176+
}
177+
else if (e.Action == NotifyCollectionChangedAction.Remove)
178+
{
179+
// add your logic here
180+
}
181+
}
182+
}
183+
```
184+
185+
**3.** Define the data model:
186+
187+
```C#
188+
public class Data
189+
{
190+
public Data(string name, int size, string type)
191+
{
192+
this.Name = name;
193+
this.Size = size;
194+
this.Type = type;
195+
this.Children = new ObservableCollection<Data>();
196+
}
197+
198+
public string Name { get; set; }
199+
public int Size { get; set; }
200+
public string Type { get; set; }
201+
public ObservableCollection<Data> Children { get; set; }
202+
}
203+
```
204+
205+
**4.** Set the binding context:
206+
207+
```XAML
208+
<ContentPage.BindingContext>
209+
<viewmodels:MainPageViewModel />
210+
</ContentPage.BindingContext>
211+
```
212+
213+
## See Also
214+
215+
- [TreeDataGrid Overview](https://docs.telerik.com/devtools/maui/controls/treedatagrid/overview)

0 commit comments

Comments
 (0)