This question is locked. New answers and comments are not allowed.
Hello,
Working on getting the orgchart example working with data pulled from a rest service asynchronously. Within OrgChartViewModel.cs I have changed this.PopulateGraphSources(); to be called asynchronously after retrieving the data and adding the node to this.HeirarchicalDataSource. After the async "this.PopulateGraphSources();" call I then check if this.ViewModesConfigured.
My nodes are added to the view, but they are stacked on top of one another and the connectors are not drawn correctly. Am I missing a step or code change to get the nodes drawn correctly asynchronously?
Thanks,
Andy
Working on getting the orgchart example working with data pulled from a rest service asynchronously. Within OrgChartViewModel.cs I have changed this.PopulateGraphSources(); to be called asynchronously after retrieving the data and adding the node to this.HeirarchicalDataSource. After the async "this.PopulateGraphSources();" call I then check if this.ViewModesConfigured.
My nodes are added to the view, but they are stacked on top of one another and the connectors are not drawn correctly. Am I missing a step or code change to get the nodes drawn correctly asynchronously?
Thanks,
Andy
6 Answers, 1 is accepted
0
Andrew
Top achievements
Rank 1
answered on 23 Jul 2014, 09:45 PM
private void PopulateWithData()
{
string projectName;
#if WPF
projectName = "OrgChart_WPF";
#else
projectName = "OrgChart_SL";
#endif
//var stream = Application.GetResourceStream(new Uri("/" + projectName + ";component/XmlSource/Ceo.xml", UriKind.RelativeOrAbsolute));
//XElement dataXml = XElement.Load(stream.Stream);
string serviceUrl = "http://corporateservicestest/HumanResources/v1/Employee/?employeeId={0}&employeeStatusCode=Active&Format=XML";
string url = string.Format(serviceUrl, ceoEmployeeId);
WebClient client = new WebClient();
client.OpenReadCompleted += new OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
client.OpenReadAsync(new Uri(url));
}
void downloader_OpenReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
if (e.Error == null)
{
XElement dataXml = XElement.Load(e.Result);
foreach (XElement element in dataXml.Descendants("employee"))
{
Node node = this.CreateNode(element, null);
node.Children.AddRange(this.GetSubNodes(element, node));
this.HierarchicalDataSource.Add(node);
}
}
this.PopulateGraphSources();
if (this.ViewModelsConfigured != null)
this.ViewModelsConfigured(this, null);
}
0
Hi Andrew,
In the handler of ViewModelsConfigured event, could you please try using the Diagram.LayoutAsync() method and let us know if this solves your scenario ? If not, is it possible for you to send us more from your code or runnable sample that we could better investigate. Thank you in advance for your cooperation.
Regards,
Petar Mladenov
Telerik
In the handler of ViewModelsConfigured event, could you please try using the Diagram.LayoutAsync() method and let us know if this solves your scenario ? If not, is it possible for you to send us more from your code or runnable sample that we could better investigate. Thank you in advance for your cooperation.
Regards,
Petar Mladenov
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
0
Andrew
Top achievements
Rank 1
answered on 28 Jul 2014, 04:37 PM
Thanks for the reply - I wasn't able to find a "LayoutAsync()" method within my Diagram assembly.
Here's a runnable sample of my OrgChartViewModel.cs file to take a look at. Thanks for any assistance!
​
Here's a runnable sample of my OrgChartViewModel.cs file to take a look at. Thanks for any assistance!
​
using
System;
using
System.Collections.Generic;
using
System.Collections.ObjectModel;
using
System.Linq;
using
System.Net;
using
System.Threading;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Threading;
using
System.Xml.Linq;
using
Telerik.Windows.Controls;
using
Telerik.Windows.Controls.Diagrams.Extensions.ViewModels;
using
Telerik.Windows.Diagrams.Core;
namespace
OrgChart.ViewModels
{
public
class
OrgChartViewModel : ViewModelBase
{
private
GraphSource graphSource;
private
TreeLayoutType currentTreeLayoutType;
private
ItemDisplayMode currentItemDisplayMode;
private
bool
shouldLayoutAfterTemplateChange;
private
bool
shouldLayoutAfterExpandCollapse;
private
TreeLayoutViewModel childTreeLayoutViewModel;
private
readonly
OrgTreeRouter router =
new
OrgTreeRouter();
private
double
zoomFactor;
private
static
double
SmallToNormalTemplateThreshHold = 0.75d;
private
static
double
NormallToLargeTemplateThreshHold = 1.4d;
private
static
string
ceoEmployeeId =
"143470"
;
public
OrgChartViewModel()
{
this
.GraphSource =
new
GraphSource();
this
.HierarchicalDataSource =
new
ObservableCollection<Node>();
this
.PopulateWithData();
//this.PopulateGraphSources();
this
.ChildRouterViewModel =
new
OrgRouterViewModel(
this
.router);
this
.ChildTreeLayoutViewModel =
new
TreeLayoutViewModel();
this
.CurrentTreeLayoutType = TreeLayoutType.TreeDown;
this
.CurrentItemDisplayMode = ItemDisplayMode.Standard;
this
.BindCommands();
this
.ShouldLayoutAfterTemplateChange =
true
;
this
.ShouldLayoutAfterExpandCollapse =
false
;
this
.ZoomFactor = 1.0d;
}
public
event
EventHandler<VisibilityChangedEventArgs> NodeVisibilityChanged;
public
event
EventHandler CurrentLayoutTypeChanged;
public
event
EventHandler CurrentLayoutTypeSettingsChanged;
public
event
EventHandler ChildrenExpandedOrCollapsed;
public
event
EventHandler ViewModelsConfigured;
public
double
ZoomFactor
{
get
{
return
this
.zoomFactor; }
set
{
if
(
this
.zoomFactor != value)
{
this
.zoomFactor = value;
this
.OnZoomChanged();
this
.OnPropertyChanged(
"ZoomFactor"
);
}
}
}
public
ItemDisplayMode CurrentItemDisplayMode
{
get
{
return
this
.currentItemDisplayMode; }
set
{
if
(
this
.currentItemDisplayMode != value)
{
this
.currentItemDisplayMode = value;
this
.OnPropertyChanged(
"CurrentItemDisplayMode"
);
}
}
}
public
TreeLayoutType CurrentTreeLayoutType
{
get
{
return
currentTreeLayoutType; }
set
{
this
.currentTreeLayoutType = value;
this
.ChildTreeLayoutViewModel.CurrentTreeLayoutType = value;
this
.ChildRouterViewModel.CurrentTreeLayoutType = value;
this
.OnPropertyChanged(
"CurrentTreeLayoutType"
);
this
.OnCurrentLayoutTypeChanged();
}
}
public
GraphSource GraphSource
{
get
{
return
this
.graphSource;
}
set
{
if
(
this
.graphSource != value)
{
this
.graphSource = value;
this
.OnPropertyChanged(
"GraphSource"
);
}
}
}
public
ObservableCollection<Node> HierarchicalDataSource {
get
;
private
set
; }
public
OrgTreeRouter Router {
get
{
return
this
.router; } }
public
DelegateCommand ToggleVisibilityCommand {
get
;
set
; }
public
TreeLayoutViewModel ChildTreeLayoutViewModel
{
get
{
return
this
.childTreeLayoutViewModel; }
protected
set
{
if
(
this
.childTreeLayoutViewModel != value)
{
this
.childTreeLayoutViewModel = value;
this
.OnPropertyChanged(
"ChildTreeLayoutViewModel"
);
}
}
}
public
OrgRouterViewModel ChildRouterViewModel {
get
;
protected
set
; }
public
bool
ShouldLayoutAfterTemplateChange
{
get
{
return
this
.shouldLayoutAfterTemplateChange; }
set
{
if
(
this
.shouldLayoutAfterTemplateChange != value)
{
this
.shouldLayoutAfterTemplateChange = value;
this
.OnPropertyChanged(
"ShouldLayoutAfterTemplateChange"
);
}
}
}
public
bool
ShouldLayoutAfterExpandCollapse
{
get
{
return
this
.shouldLayoutAfterExpandCollapse; }
set
{
if
(
this
.shouldLayoutAfterExpandCollapse != value)
{
this
.shouldLayoutAfterExpandCollapse = value;
this
.OnPropertyChanged(
"ShouldLayoutAfterExpandCollapse"
);
}
}
}
public
void
PopulateGraphSources()
{
foreach
(var item
in
this
.HierarchicalDataSource)
{
this
.GraphSource.PopulateGraphSource(item);
}
}
protected
bool
CanExecuteToggleVisibilityCommand(
object
o)
{
return
o !=
null
&& (o
as
Node).Children.Count > 0;
}
protected
void
ExecuteToggleVisibilityCommand(
object
o)
{
var node = o
as
Node;
var areChildrenCollapsed = node !=
null
&& node.AreChildrenCollapsed;
this
.ToggleChildrenVisibility(node, areChildrenCollapsed);
node.AreChildrenCollapsed = !node.AreChildrenCollapsed;
}
private
void
BindCommands()
{
this
.ToggleVisibilityCommand =
new
DelegateCommand(
this
.ExecuteToggleVisibilityCommand,
this
.CanExecuteToggleVisibilityCommand);
}
private
ObservableCollection<HierarchicalNodeViewModel> GetSubNodes(XContainer element, Node parent)
{
var nodes =
new
ObservableCollection<HierarchicalNodeViewModel>();
string
projectName;
#if WPF
projectName =
"OrgChart_WPF"
;
#else
projectName =
"OrgChart_SL"
;
#endif
var stream = Application.GetResourceStream(
new
Uri(
"/"
+ projectName +
";component/XmlSource/Organization.xml"
, UriKind.RelativeOrAbsolute));
XElement dataXml = XElement.Load(stream.Stream);
IEnumerable<XElement> children = from s
in
dataXml.Descendants(
"employee"
)
where s.Element(
"employeeManagerId"
).Value == parent.ID
select s;
foreach
(XElement subElement
in
children)
{
Node node =
this
.CreateNode(subElement, parent);
node.Children.AddRange(
this
.GetSubNodes(subElement, node));
nodes.Add(node);
}
return
nodes;
}
private
Node CreateNode(XElement element, Node parentNode)
{
Node node =
new
Node();
node.PropertyChanged +=
this
.OnNodePropertyChanged;
node.FirstName = element.Element(
"employeeFirstName"
).Value;
node.LastName = element.Element(
"employeeLastName"
).Value;
//node.Phone = element.Attribute("Phone").Value;
node.Email = element.Element(
"employeeEmailAddress"
).Value;
node.ID = element.Element(
"employeeId"
).Value;
node.ReportsTo = element.Element(
"employeeManagerId"
).Value;
node.Address = element.Element(
"employeeOfficeLocationName"
).Value;
node.Path = parentNode ==
null
? node.FullName : parentNode.Path +
"|"
+ node.FullName;
node.JobPosition = element.Element(
"employeeTitle"
).Value;
return
node;
}
private
void
OnNodePropertyChanged(
object
sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if
(e.PropertyName ==
"Visibility"
)
{
if
(
this
.NodeVisibilityChanged !=
null
)
{
this
.NodeVisibilityChanged(sender,
new
VisibilityChangedEventArgs((sender
as
Node).Visibility == Visibility.Visible));
}
}
}
private
void
PopulateWithData()
{
string
serviceUrl =
"http://corporateservicestest/HumanResources/v1/Employee/?employeeId={0}&employeeStatusCode=Active&Format=XML"
;
string
url =
string
.Format(serviceUrl, ceoEmployeeId);
WebClient client =
new
WebClient();
client.OpenReadCompleted +=
new
OpenReadCompletedEventHandler(downloader_OpenReadCompleted);
client.OpenReadAsync(
new
Uri(url));
}
void
downloader_OpenReadCompleted(
object
sender, OpenReadCompletedEventArgs e)
{
if
(e.Error ==
null
)
{
XElement dataXml = XElement.Load(e.Result);
foreach
(XElement element
in
dataXml.Descendants(
"employee"
))
{
Node node =
this
.CreateNode(element,
null
);
node.Children.AddRange(
this
.GetSubNodes(element, node));
this
.HierarchicalDataSource.Add(node);
}
}
this
.PopulateGraphSources();
if
(
this
.ViewModelsConfigured !=
null
)
this
.ViewModelsConfigured(
this
,
null
);
}
private
void
ToggleChildrenVisibility(HierarchicalNodeViewModel node,
bool
areChildrenVisible)
{
foreach
(Node subNode
in
node.Children)
{
var visibility = areChildrenVisible ? Visibility.Visible : Visibility.Collapsed;
subNode.Visibility = visibility;
subNode.IsSelected =
false
;
this
.GraphSource.InternalLinks.Where(link => link.Source == node).ToList()
.ForEach(link =>
{
link.Visibility = visibility;
link.IsSelected =
false
;
});
if
(subNode.AreChildrenCollapsed)
continue
;
this
.ToggleChildrenVisibility(subNode, areChildrenVisible);
}
this
.OnChildrenExpandedOrCollapsed();
}
private
void
OnCurrentLayoutTypeChanged()
{
if
(
this
.CurrentLayoutTypeChanged !=
null
)
{
this
.CurrentLayoutTypeChanged(
this
, EventArgs.Empty);
}
}
private
void
OnChildrenExpandedOrCollapsed()
{
if
(
this
.ChildrenExpandedOrCollapsed !=
null
)
{
this
.ChildrenExpandedOrCollapsed(
this
, EventArgs.Empty);
}
}
private
void
OnViewModelsConfigured()
{
if
(
this
.ViewModelsConfigured !=
null
)
{
//Telerik.Windows.Controls.Diagrams.L
this
.ViewModelsConfigured(
this
, EventArgs.Empty);
}
}
private
void
OnZoomChanged()
{
ItemDisplayMode newMode;
if
(SmallToNormalTemplateThreshHold <
this
.ZoomFactor &&
this
.ZoomFactor <= NormallToLargeTemplateThreshHold)
newMode = ItemDisplayMode.Standard;
else
if
(
this
.ZoomFactor <= SmallToNormalTemplateThreshHold)
newMode = ItemDisplayMode.Small;
else
newMode = ItemDisplayMode.Detailed;
if
(
this
.CurrentItemDisplayMode != newMode)
this
.ChangeAllShapesDisplayMode(newMode);
}
private
void
ChangeAllShapesDisplayMode(ItemDisplayMode newMode)
{
this
.CurrentItemDisplayMode = newMode;
foreach
(var node
in
this
.GraphSource.InternalItems)
{
node.CurrentDisplayMode = newMode;
}
}
}
public
class
VisibilityChangedEventArgs : EventArgs
{
public
VisibilityChangedEventArgs(
bool
isVisible)
{
this
.IsVisible = isVisible;
}
public
bool
IsVisible {
get
;
private
set
; }
}
}
0
Hi Andrew,
LayoutAsync() method is included in Q3 2013 Release of Telerik UI For WPF/ SIlverlight. We highly encourage you to upgrade to the latest possible version of our controls.
However, if this is not an option you can try to invoke the Layout function in Dispatcher, for example like so:
I guess you can invoke this in the ViewModelsConfigured event handler. Please let us know if this helps.
Regards,
Petar Mladenov
Telerik
LayoutAsync() method is included in Q3 2013 Release of Telerik UI For WPF/ SIlverlight. We highly encourage you to upgrade to the latest possible version of our controls.
However, if this is not an option you can try to invoke the Layout function in Dispatcher, for example like so:
Action action = new Action(() => this.diagram.Layout(...);
this.Dispatcher.BeginInvoke(action);
Regards,
Petar Mladenov
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.
0
Andrew
Top achievements
Rank 1
answered on 29 Jul 2014, 10:08 PM
So I added "this.diagram.LayoutAsync(LayoutType.Tree, null);" to public OrgChartExample() in OrgChartExample.xaml.cs, and now the nodes are no longer stacked on top of eachother, but the tree structure is still not being applied and the shapes are just lined up in 2 rows. What could I be missing?
0
Hello Andrew,
You also need to pass settings object of type TreeLayoutSettings as a parameter in the LayoutAsync Demo. Please check out this help article describing how to configure the Layout:
Diagram Layout
The main settings to configure are the Root shape of the Layout and the TreeLayoutType.
Regards,
Petar Mladenov
Telerik
You also need to pass settings object of type TreeLayoutSettings as a parameter in the LayoutAsync Demo. Please check out this help article describing how to configure the Layout:
Diagram Layout
The main settings to configure are the Root shape of the Layout and the TreeLayoutType.
Regards,
Petar Mladenov
Telerik
Check out Telerik Analytics, the service which allows developers to discover app usage patterns, analyze user data, log exceptions, solve problems and profile application performance at run time. Watch the videos and start improving your app based on facts, not hunches.