The issue manifests both when
Happens in 2.14.1 first.
*** Thread created by admin on customer behalf ***
Add checkbox support at the node level. Similar to...
https://www.telerik.com/kendo-angular-ui/components/treeview/checkboxes/
Hi,
Is there a plan to support lines between treeview items as available in radtreeview?
radTreeView1.ShowLines = true;
radTreeView1.LineStyle = TreeLineStyle.DashDot;
Without this it is very confusing to the end user what the connections between open items are.
Regards,
peter
Hello,
I am trying to fill the TreeView using an async method. The first level is loaded an expanded. Subsequent levels are not. Or so it seams. They are loaded, but when expanding a node it expands and immediately collapses. Expanding a second time reveals the nodes loaded earlier.
I included a demo project. Open http://localhost:{port}/tree.
Best regards,
Marcel Gelijk
Repro plus workaround (already in):
<button @onclick="@SwitchDataSource">switch to other data source</button>
<TelerikTreeView Data="@FlatData">
<TreeViewBindings>
<TreeViewBinding IdField="Id" ParentIdField="ParentIdValue" ExpandedField="Expanded" TextField="Text"
HasChildrenField="HasChildren" IconField="Icon">
<ItemTemplate>
@{
TreeItem currProduct = context as TreeItem;
@(currProduct.Text)
}
</ItemTemplate>
</TreeViewBinding>
</TreeViewBindings>
</TelerikTreeView>
@code {
public class TreeItem
{
public int Id { get; set; }
public string Text { get; set; }
public int? ParentIdValue { get; set; }
public bool HasChildren { get; set; }
public string Icon { get; set; }
public bool Expanded { get; set; }
}
async void SwitchDataSource()
{
//workaround - remove it to see the actual error
foreach (TreeItem item in FlatData)
{
item.Expanded = false;
}
StateHasChanged();
await Task.Delay(300);//awaits the animation that will hide the nodes we just collapsed so their elements get properly disposed
//change data
LoadSecondDataSource();
//update UI
StateHasChanged();
}
public IEnumerable<TreeItem> FlatData { get; set; }
protected override void OnInitialized()
{
LoadFlatData();
}
private void LoadFlatData()
{
List<TreeItem> items = new List<TreeItem>();
items.Add(new TreeItem()
{
Id = 1,
Text = "Project",
ParentIdValue = null,
HasChildren = true,
Icon = "folder",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 2,
Text = "Design",
ParentIdValue = 1,
HasChildren = true,
Icon = "brush",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 3,
Text = "Implementation",
ParentIdValue = 1,
HasChildren = true,
Icon = "folder",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 4,
Text = "site.psd",
ParentIdValue = 2,
HasChildren = false,
Icon = "psd",
Expanded = true
});
items.Add(new TreeItem()
{
Id = 5,
Text = "index.js",
ParentIdValue = 3,
HasChildren = false,
Icon = "js"
});
items.Add(new TreeItem()
{
Id = 6,
Text = "index.html",
ParentIdValue = 3,
HasChildren = false,
Icon = "html"
});
items.Add(new TreeItem()
{
Id = 7,
Text = "styles.css",
ParentIdValue = 3,
HasChildren = false,
Icon = "css"
});
FlatData = items;
}
void LoadSecondDataSource()
{
List<TreeItem> items = new List<TreeItem>();
items.Add(new TreeItem()
{
Id = 1,
Text = "1",
ParentIdValue = null,
HasChildren = true
});
items.Add(new TreeItem()
{
Id = 2,
Text = "1 1",
ParentIdValue = 1,
HasChildren = true
});
//if you add this, there is no error because the levels match
//if the new data source does not have the same number of (maybe expanded) levels
//you will get an error while disposing those levels
//items.Add(new TreeItem()
//{
// Id = 3,
// Text = "1 1 1",
// ParentIdValue = 2
//});
FlatData = items;
}
}
Hi everyone,
We created this item to request your feedback on how you use the treeview binding with regards to the Expanded state of the nodes.
At the moment, the treeview updates the field in the collection when an item gets expanded or collapsed, and that makes it unique in the suite - the other data bound components do not alter their data source silently, and this is the general pattern we want to follow in order to have consistency across the board.
Thus, there are several approaches we are considering and we want to get your take on how you would find this most comfortable:
I have an extensive WPF background and so I naturally use ObservableCollection for virtually all UI type binding scenarios.
However I noticed that it seems the TreeView control doesn't seem to work when bound that way.
I switched the property to an array instead and it worked with no other modifications.
I need to be able to multiselect items in a treeview and drag n drop to reorder items.
(Same as RadTreeView AJAX component)
Add the following Razor component and run. Click around tree, especially from disclosure icon to node to 'plus' icon. Error will occur.
=====================================
@page "/poopy"
@using Microsoft.AspNetCore.Components
@using Telerik.Blazor
@using Telerik.Blazor.Components
@using Telerik.Blazor.Components.Button
<style>
.k-mid:hover .showme {
display: block;
}
.showme {
display: none;
margin-left: 10px;
}
.showhim:hover .showme {
display: block;
}
</style>
@using Telerik.Blazor.Components.TreeView
<TelerikTreeView Data="@TreeData">
<TelerikTreeViewBindings>
<TelerikTreeViewBinding IdField="Id" ParentIdField="ParentIdValue" ExpandedField="Expanded" HasChildrenField="HasChildren">
<ItemTemplate>
<div @onclick="@(_ => NodeClicked((context as TreeItem).Text))" style="cursor: pointer">@((context as TreeItem).Text)</div>
<div class="showme" @onclick="SayHelloHandler" style="cursor: pointer">
<TelerikIcon IconName="@IconName.Plus" />
</div>
</ItemTemplate>
</TelerikTreeViewBinding>
</TelerikTreeViewBindings>
</TelerikTreeView>
@helloString
@code {
MarkupString helloString;
void NodeClicked(string node)
{
helloString = new MarkupString(node);
}
void SayHelloHandler()
{
string msg = $"Hello from <strong>Telerik Blazor</strong> at {DateTime.Now}.<br /> Now you can use C# to write front-end!";
helloString = new MarkupString(msg);
}
public class TreeItem
{
public int Id { get; set; }
public string Text { get; set; }
public int? ParentIdValue { get; set; }
public bool HasChildren { get; set; }
public bool Expanded { get; set; }
}
public IEnumerable<TreeItem> TreeData { get; set; }
protected override void OnInitialized()
{
LoadTreeData();
}
private void LoadTreeData()
{
List<TreeItem> items = new List<TreeItem>();
items.Add(new TreeItem()
{
Id = 1,
Text = "Project",
ParentIdValue = null,
HasChildren = true,
Expanded = true
});
items.Add(new TreeItem()
{
Id = 2,
Text = "Design",
ParentIdValue = 1,
HasChildren = false,
Expanded = true
});
items.Add(new TreeItem()
{
Id = 3,
Text = "Implementation",
ParentIdValue = 1,
HasChildren = false,
Expanded = true
});
TreeData = items;
}
}
======================================
Microsoft.JSInterop.JSException
HResult=0x80131500@
using
Telerik.Blazor.Components.TreeView
<button
class
=
"btn btn-primary"
@onclick=
"@(() => ChangeTreeData(false))"
>Change tree data</button>
<TelerikTreeView Data=
"@FlatData"
>
<TelerikTreeViewBindings>
<TelerikTreeViewBinding ParentIdField=
"Parent"
ExpandedField=
"IsExpanded"
></TelerikTreeViewBinding>
</TelerikTreeViewBindings>
</TelerikTreeView>
@code {
public
List<TreeItem> FlatData {
get
;
set
; } =
new
List<TreeItem>();
public
class
TreeItem
//most fields use the default names and will bind automatically in this example
{
public
int
Id {
get
;
set
; }
public
string
Text {
get
;
set
; }
public
int
? Parent {
get
;
set
; }
//this is a non-default field name
public
bool
HasChildren {
get
;
set
; }
public
bool
IsExpanded {
get
;
set
; }
//this is a non-default field name
}
protected
override
void
OnInit()
{
ChangeTreeData(
true
);
}
int
currIndex {
get
;
set
; } = 0;
void
ChangeTreeData(
bool
expandItems)
{
currIndex++;
FlatData.Clear();
List<TreeItem> data =
new
List<TreeItem>();
data.Add(
new
TreeItem { Id = currIndex, HasChildren =
true
, IsExpanded = expandItems, Parent =
null
, Text = $
"root {currIndex}"
});
data.Add(
new
TreeItem { Id = currIndex + 1, HasChildren =
false
, IsExpanded = expandItems, Parent = currIndex, Text = $
"root {currIndex}: child one"
});
FlatData.AddRange(data);
}
}
I would like a node click event exposed from the treeview.
At the moment, you need to use a template. Example and considerations are available in the following forum thread: https://www.telerik.com/forums/row-click-and-double-click-events#PQpO8DcbzkCArF3UqoLcWA.
When using load-on-demand, you may not know how much data there is and how many levels deep it will go. You need the OnExpand event to fire for each node so you can call your services and retrieve data.
Unfortunately, it does not fire for the second level of nodes, so you cannot load data for them.