#develop (short for SharpDevelop) is a free IDE for .NET programming languages.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

239 lines
7.7 KiB

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Controls;
using System.Windows;
using System.ComponentModel;
using System.Reflection;
using System.Windows.Data;
namespace TreeMaps.Controls
{
[TemplatePart(Name = TreeMapItem.HeaderPartName, Type = typeof(FrameworkElement))]
public class TreeMapItem : HeaderedItemsControl
{
#region consts
private const string HeaderPartName = "PART_Header";
#endregion
#region fields
private double _area;
private TreeMaps _parentTreeMaps;
#endregion
#region dependency properties
public static DependencyProperty TreeMapModeProperty
= DependencyProperty.Register("TreeMapMode", typeof(TreeMapAlgo), typeof(TreeMapItem), new FrameworkPropertyMetadata(TreeMapAlgo.Squarified,FrameworkPropertyMetadataOptions.AffectsMeasure | FrameworkPropertyMetadataOptions.AffectsArrange));
public static readonly DependencyProperty ValuePropertyNameProperty
= DependencyProperty.Register("ValuePropertyName", typeof(string), typeof(TreeMapItem), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsParentArrange | FrameworkPropertyMetadataOptions.AffectsParentMeasure));
public static readonly DependencyProperty LevelProperty
= DependencyProperty.Register("Level", typeof(int), typeof(TreeMapItem),new FrameworkPropertyMetadata(0,FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty MaxDepthProperty
= DependencyProperty.Register("MaxDepth", typeof(int), typeof(TreeMapItem),new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty MinAreaProperty
= DependencyProperty.Register("MinArea", typeof(int), typeof(TreeMapItem), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsRender));
public static readonly DependencyProperty ShouldRecurseProperty
= DependencyProperty.Register("ShouldRecurse", typeof(bool), typeof(TreeMapItem), new FrameworkPropertyMetadata(true, FrameworkPropertyMetadataOptions.AffectsRender));
#endregion
#region ctors
static TreeMapItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(TreeMapItem), new FrameworkPropertyMetadata(typeof(TreeMapItem)));
}
public TreeMapItem()
{
this.VerticalAlignment = VerticalAlignment.Stretch;
this.HorizontalAlignment = HorizontalAlignment.Stretch;
this.VerticalContentAlignment = VerticalAlignment.Stretch;
this.HorizontalContentAlignment = HorizontalAlignment.Stretch;
this.SnapsToDevicePixels = true;
}
public TreeMapItem(int level, int maxDepth, int minArea, string valuePropertyName)
: this()
{
this.ValuePropertyName = valuePropertyName;
this.Level = level;
this.MaxDepth = maxDepth;
this.MinArea = minArea;
}
#endregion
#region properties
public TreeMapAlgo TreeMapMode
{
get { return (TreeMapAlgo)this.GetValue(TreeMapItem.TreeMapModeProperty); }
set { this.SetValue(TreeMapItem.TreeMapModeProperty, value); }
}
public string ValuePropertyName
{
get { return (string)this.GetValue(TreeMapItem.ValuePropertyNameProperty); }
set { this.SetValue(TreeMapItem.ValuePropertyNameProperty, value); }
}
public int MaxDepth
{
get { return (int)this.GetValue(TreeMapItem.MaxDepthProperty); }
internal set { this.SetValue(TreeMapItem.MaxDepthProperty, value); }
}
public int MinArea
{
get { return (int)this.GetValue(TreeMapItem.MinAreaProperty); }
internal set { this.SetValue(TreeMapItem.MinAreaProperty, value); }
}
public bool ShouldRecurse
{
get { return (bool)this.GetValue(TreeMapItem.ShouldRecurseProperty); }
internal set { this.SetValue(TreeMapItem.ShouldRecurseProperty, value); }
}
public int Level
{
get { return (int)this.GetValue(TreeMapItem.LevelProperty); }
set { this.SetValue(TreeMapItem.LevelProperty, value); }
}
internal double Area
{
get { return _area; }
}
internal ItemsControl ParentItemsControl
{
get { return ItemsControl.ItemsControlFromItemContainer(this); }
}
internal TreeMaps ParentTreeMap
{
get
{
for (ItemsControl control = this.ParentItemsControl; control != null; control = ItemsControl.ItemsControlFromItemContainer(control))
{
TreeMaps view = control as TreeMaps;
if (view != null)
return view;
}
return null;
}
}
internal TreeMapItem ParentTreeMapItem
{
get { return (this.ParentItemsControl as TreeMapItem); }
}
#endregion
#region protected methods
protected override Size ArrangeOverride(Size arrangeBounds)
{
Size size = base.ArrangeOverride(arrangeBounds);
if (this.IsValidSize(size))
_area = size.Width * size.Height;
else
_area = 0;
this.UpdateShouldRecurse();
return size;
}
protected override DependencyObject GetContainerForItemOverride()
{
return new TreeMapItem(this.Level+1,this.MaxDepth,this.MinArea,this.ValuePropertyName);
}
protected override void OnVisualParentChanged(DependencyObject oldParent)
{
base.OnVisualParentChanged(oldParent);
_parentTreeMaps = this.ParentTreeMap;
if (_parentTreeMaps != null)
{
Binding bindingMode = new Binding(TreeMaps.TreeMapModeProperty.Name);
bindingMode.Source = _parentTreeMaps;
BindingOperations.SetBinding(this, TreeMapItem.TreeMapModeProperty, bindingMode);
Binding bindingValue = new Binding(TreeMaps.ValuePropertyNameProperty.Name);
bindingValue.Source = _parentTreeMaps;
BindingOperations.SetBinding(this, TreeMapItem.ValuePropertyNameProperty, bindingValue);
Binding bindingMinArea = new Binding(TreeMaps.MinAreaProperty.Name);
bindingMinArea.Source = _parentTreeMaps;
BindingOperations.SetBinding(this, TreeMapItem.MinAreaProperty, bindingMinArea);
Binding bindingMaxDepth = new Binding(TreeMaps.MaxDepthProperty.Name);
bindingMaxDepth.Source = _parentTreeMaps;
BindingOperations.SetBinding(this, TreeMapItem.MaxDepthProperty, bindingMaxDepth);
}
}
protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
{
base.OnPropertyChanged(e);
if (e.Property == TreeMapItem.ValuePropertyNameProperty || e.Property == TreeMapItem.DataContextProperty)
{
if (this.ValuePropertyName != null && this.DataContext != null)
{
Binding binding = new Binding(this.ValuePropertyName);
binding.Source = this.DataContext;
BindingOperations.SetBinding(this, TreeMapsPanel.WeightProperty, binding);
}
}
else if (e.Property == TreeMapItem.MaxDepthProperty)
this.UpdateShouldRecurse();
else if (e.Property == TreeMapItem.MinAreaProperty)
this.UpdateShouldRecurse();
else if (e.Property == TreeMapItem.LevelProperty)
this.UpdateShouldRecurse();
}
protected override bool IsItemItsOwnContainerOverride(object item)
{
return (item is TreeMapItem);
}
#endregion
#region private methods
private bool IsValidSize(Size size)
{
return (!size.IsEmpty && size.Width > 0 && size.Width != double.NaN && size.Height > 0 && size.Height != double.NaN);
}
private void UpdateShouldRecurse()
{
if (!this.HasHeader)
{
this.ShouldRecurse = false;
return;
}
this.ShouldRecurse = ((this.MaxDepth == 0) || (this.Level < this.MaxDepth)) && ((this.MinArea == 0) || (this.Area >this.MinArea));
}
#endregion
}
}