Browse Source

TreeView work in progress...

pull/4/head
Steven Kirk 12 years ago
parent
commit
c9ee3847ce
  1. 26
      Perspex.UnitTests/PerspexObjectTests.cs
  2. 26
      Perspex.UnitTests/PriorityValueTEsts.cs
  3. 7
      Perspex/Controls/DataTemplate.cs
  4. 25
      Perspex/Controls/HeaderedItemsControl.cs
  5. 25
      Perspex/Controls/ItemsControl.cs
  6. 9
      Perspex/Controls/ItemsPresenter.cs
  7. 6
      Perspex/Controls/TabStrip.cs
  8. 58
      Perspex/Controls/TreeDataTemplate.cs
  9. 47
      Perspex/Controls/TreeView.cs
  10. 17
      Perspex/Controls/TreeViewItem.cs
  11. 6
      Perspex/Perspex.csproj
  12. 18
      Perspex/PerspexObject.cs
  13. 10
      Perspex/PerspexProperty.cs
  14. 59
      Perspex/PriorityValue.cs
  15. 2
      Perspex/Themes/Default/DefaultTheme.cs
  16. 1
      Perspex/Themes/Default/ItemsControlStyle.cs
  17. 1
      Perspex/Themes/Default/TabStripStyle.cs
  18. 49
      Perspex/Themes/Default/TreeViewItemStyle.cs
  19. 38
      Perspex/Themes/Default/TreeViewStyle.cs
  20. 189
      TestApplication/Program.cs

26
Perspex.UnitTests/PerspexObjectTests.cs

@ -161,6 +161,15 @@ namespace Perspex.UnitTests
target.SetValue(Class2.BarProperty, "invalid");
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void SetValue_Throws_Exception_For_Invalid_Value_Type()
{
Class1 target = new Class1();
target.SetValue(Class1.FooProperty, 123);
}
[TestMethod]
public void GetObservable_Returns_Initial_Value()
{
@ -271,7 +280,7 @@ namespace Perspex.UnitTests
}
[TestMethod]
public void Binding_Sets_Current_Value()
public void Bind_Sets_Current_Value()
{
Class1 target = new Class1();
Class1 source = new Class1();
@ -283,7 +292,7 @@ namespace Perspex.UnitTests
}
[TestMethod]
public void Binding_NonGeneric_Sets_Current_Value()
public void Bind_NonGeneric_Sets_Current_Value()
{
Class1 target = new Class1();
Class1 source = new Class1();
@ -295,7 +304,7 @@ namespace Perspex.UnitTests
}
[TestMethod]
public void Binding_Sets_Subsequent_Value()
public void Bind_Sets_Subsequent_Value()
{
Class1 target = new Class1();
Class1 source = new Class1();
@ -322,7 +331,7 @@ namespace Perspex.UnitTests
}
[TestMethod]
public void Binding_Doesnt_Set_Value_After_Reset()
public void Bind_Doesnt_Set_Value_After_Reset()
{
Class1 target = new Class1();
Class1 source = new Class1();
@ -335,6 +344,15 @@ namespace Perspex.UnitTests
Assert.AreEqual("reset", target.GetValue(Class1.FooProperty));
}
[TestMethod]
[ExpectedException(typeof(InvalidOperationException))]
public void Bind_Throws_Exception_For_Invalid_Value_Type()
{
Class1 target = new Class1();
target.Bind((PerspexProperty)Class1.FooProperty, Observable.Return((object)123));
}
[TestMethod]
public void Setting_UnsetValue_Reverts_To_Default_Value()
{

26
Perspex.UnitTests/PriorityValueTEsts.cs

@ -19,7 +19,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Initial_Value_Should_Be_UnsetValue()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
Assert.AreSame(PerspexProperty.UnsetValue, target.Value);
}
@ -27,7 +27,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void First_Binding_Sets_Value()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
target.Add(this.Single("foo"), 0);
@ -37,7 +37,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Changing_Binding_Should_Set_Value()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<string>("foo");
target.Add(subject, 0);
@ -49,7 +49,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Binding_With_Lower_Priority_Has_Precedence()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
target.Add(this.Single("foo"), 1);
target.Add(this.Single("bar"), 0);
@ -61,7 +61,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Later_Binding_With_Same_Priority_Should_Take_Precedence()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
target.Add(this.Single("foo"), 1);
target.Add(this.Single("bar"), 0);
@ -74,7 +74,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Changing_Binding_With_Lower_Priority_Should_Set_Not_Value()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<string>("bar");
target.Add(this.Single("foo"), 0);
@ -87,7 +87,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void UnsetValue_Should_Fall_Back_To_Next_Binding()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<object>("bar");
target.Add(subject, 0);
@ -103,7 +103,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Adding_Value_Should_Call_OnNext()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
bool called = false;
target.Changed.Subscribe(value => called = (value.Item1 == PerspexProperty.UnsetValue && (string)value.Item2 == "foo"));
@ -115,7 +115,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Changing_Value_Should_Call_OnNext()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<object>("foo");
bool called = false;
@ -129,7 +129,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Disposing_A_Binding_Should_Revert_To_Next_Value()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
target.Add(this.Single("foo"), 0);
var disposable = target.Add(this.Single("bar"), 0);
@ -142,7 +142,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Disposing_A_Binding_Should_Remove_BindingEntry()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
target.Add(this.Single("foo"), 0);
var disposable = target.Add(this.Single("bar"), 0);
@ -155,7 +155,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Completing_A_Binding_Should_Revert_To_Next_Value()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<object>("bar");
target.Add(this.Single("foo"), 0);
@ -169,7 +169,7 @@ namespace Perspex.UnitTests
[TestMethod]
public void Completing_A_Binding_Should_Remove_BindingEntry()
{
var target = new PriorityValue();
var target = new PriorityValue("Test", typeof(string));
var subject = new BehaviorSubject<object>("bar");
target.Add(this.Single("foo"), 0);

7
Perspex/Controls/DataTemplate.cs

@ -20,7 +20,7 @@ namespace Perspex.Controls
}
public DataTemplate(Type type, Func<object, Control> build)
: this(o => type.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()), build)
: this(o => IsInstance(o, type), build)
{
}
@ -33,6 +33,11 @@ namespace Perspex.Controls
this.Build = build;
}
public static bool IsInstance(object o, Type t)
{
return t.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo());
}
public Func<object, bool> Match { get; private set; }
public Func<object, Control> Build { get; private set; }

25
Perspex/Controls/HeaderedItemsControl.cs

@ -0,0 +1,25 @@
// -----------------------------------------------------------------------
// <copyright file="HeaderedItemsControl.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using System.Collections;
using System.Linq;
using System.Reactive.Linq;
public class HeaderedItemsControl : ItemsControl
{
public static readonly PerspexProperty<object> HeaderProperty =
HeaderedContentControl.HeaderProperty.AddOwner<HeaderedItemsControl>();
public object Header
{
get { return this.GetValue(HeaderProperty); }
set { this.SetValue(HeaderProperty, value); }
}
}
}

25
Perspex/Controls/ItemsControl.cs

@ -21,9 +21,6 @@ namespace Perspex.Controls
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel", defaultValue: DefaultPanel);
public static readonly PerspexProperty<DataTemplate> ItemTemplateProperty =
PerspexProperty.Register<ItemsControl, DataTemplate>("ItemTemplate");
private Dictionary<object, Control> itemControls = new Dictionary<object, Control>();
public IEnumerable Items
@ -38,12 +35,6 @@ namespace Perspex.Controls
set { this.SetValue(ItemsPanelProperty, value); }
}
public DataTemplate ItemTemplate
{
get { return this.GetValue(ItemTemplateProperty); }
set { this.SetValue(ItemTemplateProperty, value); }
}
public Control GetControlForItem(object item)
{
Control result;
@ -65,21 +56,7 @@ namespace Perspex.Controls
protected virtual Control CreateItemControlOverride(object item)
{
Control control = item as Control;
DataTemplate template = this.ItemTemplate;
if (control != null)
{
return control;
}
else if (template != null)
{
return template.Build(item);
}
else
{
return this.GetDataTemplate(item).Build(item);
}
return (item as Control) ?? this.GetDataTemplate(item).Build(item);
}
}
}

9
Perspex/Controls/ItemsPresenter.cs

@ -20,9 +20,6 @@ namespace Perspex.Controls
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
ItemsControl.ItemsPanelProperty.AddOwner<ItemsPresenter>();
public static readonly PerspexProperty<DataTemplate> ItemTemplateProperty =
ItemsControl.ItemTemplateProperty.AddOwner<ItemsPresenter>();
private Panel panel;
public ItemsPresenter()
@ -42,12 +39,6 @@ namespace Perspex.Controls
set { this.SetValue(ItemsPanelProperty, value); }
}
public DataTemplate ItemTemplate
{
get { return this.GetValue(ItemTemplateProperty); }
set { this.SetValue(ItemTemplateProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); }

6
Perspex/Controls/TabStrip.cs

@ -14,13 +14,9 @@ namespace Perspex.Controls
private static readonly ItemsPanelTemplate PanelTemplate = new ItemsPanelTemplate(
() => new StackPanel());
private static readonly DataTemplate TabTemplate = new DataTemplate(
o => new TabItem { Content = o });
static TabStrip()
{
ItemsPanelProperty.OverrideDefaultValue(typeof(TabStrip), PanelTemplate);
ItemTemplateProperty.OverrideDefaultValue(typeof(TabStrip), TabTemplate);
}
public TabStrip()
@ -37,7 +33,7 @@ namespace Perspex.Controls
{
result = new TabItem
{
Content = item,
Content = this.GetDataTemplate(item).Build(item),
};
}

58
Perspex/Controls/TreeDataTemplate.cs

@ -0,0 +1,58 @@
// -----------------------------------------------------------------------
// <copyright file="TreeDataTemplate.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using System.Collections;
public class TreeDataTemplate : DataTemplate
{
public TreeDataTemplate(
Func<object, Control> build,
Func<object, IEnumerable> itemsSelector)
: this(o => true, build, itemsSelector)
{
}
public TreeDataTemplate(
Type type,
Func<object, Control> build,
Func<object, IEnumerable> itemsSelector)
: this(o => IsInstance(o, type), build, itemsSelector)
{
}
public TreeDataTemplate(
Func<object, bool> match,
Func<object, Control> build,
Func<object, IEnumerable> itemsSelector)
: base(match, build)
{
this.ItemsSelector = itemsSelector;
}
public Func<object, IEnumerable> ItemsSelector { get; private set; }
}
public class TreeDataTemplate<T> : TreeDataTemplate
{
public TreeDataTemplate(
Func<object, Control> build,
Func<T, IEnumerable> itemsSelector)
: base(typeof(T), o => build((T)o), o => itemsSelector((T)o))
{
}
public TreeDataTemplate(
Func<T, bool> match,
Func<T, Control> build,
Func<T, IEnumerable> itemsSelector)
: base(o => (o is T) ? match((T)o) : false, o => build((T)o), o => itemsSelector((T)o))
{
}
}
}

47
Perspex/Controls/TreeView.cs

@ -0,0 +1,47 @@
// -----------------------------------------------------------------------
// <copyright file="TreeView.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using System.Collections;
using System.Linq;
using System.Reactive.Linq;
public class TreeView : SelectingItemsControl
{
protected override Control CreateItemControlOverride(object item)
{
TreeViewItem result = item as TreeViewItem;
if (result == null)
{
TreeDataTemplate template = this.GetTreeDataTemplate(item);
result = new TreeViewItem
{
Header = template.Build(item),
Items = template.ItemsSelector(item),
};
}
return result;
}
private TreeDataTemplate GetTreeDataTemplate(object item)
{
DataTemplate template = this.GetDataTemplate(item);
TreeDataTemplate treeTemplate = template as TreeDataTemplate;
if (treeTemplate == null)
{
treeTemplate = new TreeDataTemplate(template.Build, x => null);
}
return treeTemplate;
}
}
}

17
Perspex/Controls/TreeViewItem.cs

@ -0,0 +1,17 @@
// -----------------------------------------------------------------------
// <copyright file="TreeViewItem.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Controls
{
using System;
using System.Collections;
using System.Linq;
using System.Reactive.Linq;
public class TreeViewItem : HeaderedItemsControl
{
}
}

6
Perspex/Perspex.csproj

@ -70,9 +70,13 @@
<ItemGroup>
<Compile Include="Application.cs" />
<Compile Include="BindingExtensions.cs" />
<Compile Include="Controls\TreeDataTemplate.cs" />
<Compile Include="Controls\HeaderedContentControl.cs" />
<Compile Include="Controls\Controls.cs" />
<Compile Include="Controls\SelectingItemsControl.cs" />
<Compile Include="Controls\HeaderedItemsControl.cs" />
<Compile Include="Controls\TreeViewItem.cs" />
<Compile Include="Controls\TreeView.cs" />
<Compile Include="Controls\TabItem.cs" />
<Compile Include="Controls\TabControl.cs" />
<Compile Include="Controls\TabStrip.cs" />
@ -135,6 +139,8 @@
<Compile Include="Media\Geometry.cs" />
<Compile Include="Media\Stretch.cs" />
<Compile Include="Themes\Default\ContentControlStyle.cs" />
<Compile Include="Themes\Default\TreeViewItemStyle.cs" />
<Compile Include="Themes\Default\TreeViewStyle.cs" />
<Compile Include="Themes\Default\ItemsControlStyle.cs" />
<Compile Include="Themes\Default\TabItemStyle.cs" />
<Compile Include="Themes\Default\TabControlStyle.cs" />

18
Perspex/PerspexObject.cs

@ -43,6 +43,11 @@ namespace Perspex
/// A style binding.
/// </summary>
Style,
/// <summary>
/// The binding is uninitialized.
/// </summary>
Unset = int.MaxValue,
}
/// <summary>
@ -200,7 +205,7 @@ namespace Perspex
}
/// <summary>
/// Clears a <see cref="PerspexProperty"/> value, including its binding.
/// Clears a <see cref="PerspexProperty"/>'s local value.
/// </summary>
/// <param name="property">The property.</param>
public void ClearValue(PerspexProperty property)
@ -394,6 +399,15 @@ namespace Perspex
this.GetType()));
}
if (!PriorityValue.IsValidValue(value, property.PropertyType))
{
throw new InvalidOperationException(string.Format(
"Invalid value for Property '{0}': {1} ({2})",
property.Name,
value,
value.GetType().FullName));
}
if (!this.values.TryGetValue(property, out v))
{
if (value == PerspexProperty.UnsetValue)
@ -493,7 +507,7 @@ namespace Perspex
private PriorityValue CreatePriorityValue(PerspexProperty property)
{
PriorityValue result = new PriorityValue();
PriorityValue result = new PriorityValue(property.Name, property.PropertyType);
result.Changed.Subscribe(x =>
{

10
Perspex/PerspexProperty.cs

@ -25,7 +25,7 @@ namespace Perspex
/// <summary>
/// Represents an unset property value.
/// </summary>
public static readonly object UnsetValue = new object();
public static readonly object UnsetValue = new Unset();
/// <summary>
/// The default values for the property, by type.
@ -259,6 +259,14 @@ namespace Perspex
private set;
}
}
private class Unset
{
public override string ToString()
{
return "{Unset}";
}
}
}
/// <summary>

59
Perspex/PriorityValue.cs

@ -10,6 +10,7 @@ namespace Perspex
using System.Collections.Generic;
using System.Reactive.Disposables;
using System.Reactive.Subjects;
using System.Reflection;
/// <summary>
/// Maintains a list of prioritised bindings together with a current value.
@ -25,6 +26,16 @@ namespace Perspex
/// </remarks>
public class PriorityValue
{
/// <summary>
/// The name of the property.
/// </summary>
private string name;
/// <summary>
/// The value type.
/// </summary>
private Type valueType;
/// <summary>
/// The currently registered binding entries.
/// </summary>
@ -43,8 +54,12 @@ namespace Perspex
/// <summary>
/// Initializes a new instance of the <see cref="PriorityValue"/> class.
/// </summary>
public PriorityValue()
/// <param name="name">The name of the property.</param>
/// <param name="valueType">The value type.</param>
public PriorityValue(string name, Type valueType)
{
this.name = name;
this.valueType = valueType;
this.value = PerspexProperty.UnsetValue;
this.ValuePriority = int.MaxValue;
}
@ -74,6 +89,39 @@ namespace Perspex
private set;
}
/// <summary>
/// Checks whether a value is valid for a type.
/// </summary>
/// <param name="value"></param>
/// <param name="propertyType"></param>
/// <returns></returns>
public static bool IsValidValue(object value, Type propertyType)
{
TypeInfo type = propertyType.GetTypeInfo();
if (value == PerspexProperty.UnsetValue)
{
return true;
}
else if (value == null)
{
if (type.IsValueType &&
(!type.IsGenericType || !(type.GetGenericTypeDefinition() == typeof(Nullable<>))))
{
return false;
}
}
else
{
if (!type.IsAssignableFrom(value.GetType().GetTypeInfo()))
{
return false;
}
}
return true;
}
/// <summary>
/// Adds a new binding.
/// </summary>
@ -218,6 +266,15 @@ namespace Perspex
/// <param name="priority">The priority of the binding which produced the value.</param>
private void SetValue(object value, int priority)
{
if (!IsValidValue(value, this.valueType))
{
throw new InvalidOperationException(string.Format(
"Invalid value for Property '{0}': {1} ({2})",
this.name,
value,
value.GetType().FullName));
}
object old = this.value;
this.ValuePriority = priority;

2
Perspex/Themes/Default/DefaultTheme.cs

@ -20,6 +20,8 @@ namespace Perspex.Themes.Default
this.Add(new TabItemStyle());
this.Add(new TabStripStyle());
this.Add(new TextBoxStyle());
this.Add(new TreeViewStyle());
this.Add(new TreeViewItemStyle());
}
}
}

1
Perspex/Themes/Default/ItemsControlStyle.cs

@ -32,7 +32,6 @@ namespace Perspex.Themes.Default
{
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~ItemsPresenter.ItemTemplateProperty] = control[~ItemsControl.ItemTemplateProperty],
};
}
}

1
Perspex/Themes/Default/TabStripStyle.cs

@ -40,7 +40,6 @@ namespace Perspex.Themes.Default
{
[~ItemsPresenter.ItemsProperty] = control[~ItemsControl.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~ItemsControl.ItemsPanelProperty],
[~ItemsPresenter.ItemTemplateProperty] = control[~ItemsControl.ItemTemplateProperty],
};
}
}

49
Perspex/Themes/Default/TreeViewItemStyle.cs

@ -0,0 +1,49 @@
// -----------------------------------------------------------------------
// <copyright file="TreeViewItemStyle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Themes.Default
{
using System.Linq;
using Perspex.Controls;
using Perspex.Styling;
public class TreeViewItemStyle : Styles
{
public TreeViewItemStyle()
{
this.AddRange(new[]
{
new Style(x => x.OfType<TreeViewItem>())
{
Setters = new[]
{
new Setter(Button.TemplateProperty, ControlTemplate.Create<TreeViewItem>(this.Template)),
},
},
});
}
private Control Template(TreeViewItem control)
{
return new StackPanel
{
Children = new Controls
{
new ContentPresenter
{
[~ContentPresenter.ContentProperty] = control[~TreeViewItem.HeaderProperty],
},
new ItemsPresenter
{
Margin = new Thickness(13, 0, 0, 0),
[~ItemsPresenter.ItemsProperty] = control[~TreeViewItem.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~TreeViewItem.ItemsPanelProperty],
}
}
};
}
}
}

38
Perspex/Themes/Default/TreeViewStyle.cs

@ -0,0 +1,38 @@
// -----------------------------------------------------------------------
// <copyright file="TreeViewStyle.cs" company="Steven Kirk">
// Copyright 2014 MIT Licence. See licence.md for more information.
// </copyright>
// -----------------------------------------------------------------------
namespace Perspex.Themes.Default
{
using System.Linq;
using Perspex.Controls;
using Perspex.Styling;
public class TreeViewStyle : Styles
{
public TreeViewStyle()
{
this.AddRange(new[]
{
new Style(x => x.OfType<TreeView>())
{
Setters = new[]
{
new Setter(Button.TemplateProperty, ControlTemplate.Create<TreeView>(this.Template)),
},
},
});
}
private Control Template(TreeView control)
{
return new ItemsPresenter
{
[~ItemsPresenter.ItemsProperty] = control[~TreeView.ItemsProperty],
[~ItemsPresenter.ItemsPanelProperty] = control[~TreeView.ItemsPanelProperty],
};
}
}
}

189
TestApplication/Program.cs

@ -1,4 +1,6 @@
using Perspex;
using System.Collections;
using System.Collections.Generic;
using Perspex;
using Perspex.Controls;
using Perspex.Layout;
using Perspex.Media;
@ -30,74 +32,146 @@ namespace TestApplication
public string Value { get; set; }
}
class Node
{
public string Name { get; set; }
public IEnumerable<Node> Children { get; set; }
}
class Program
{
static void Main(string[] args)
private static Node[] treeData = new[]
{
App application = new App();
new Node
{
Name = "Root 1",
Children = new[]
{
new Node
{
Name = "Child 1",
},
new Node
{
Name = "Child 2",
Children = new[]
{
new Node
{
Name = "Grandchild 1",
},
new Node
{
Name = "Grandmaster Flash",
},
}
},
new Node
{
Name = "Child 3",
},
}
},
new Node
{
Name = "Root 2",
},
};
static void Main(string[] args)
{
//Locator.CurrentMutable.Register(() => new TestLogger { Level = LogLevel.Debug } , typeof(ILogger));
App application = new App
{
DataTemplates = new DataTemplates
{
new TreeDataTemplate<Node>(
x => new TextBlock { Text = x.ToString() },
x => x.Children),
},
};
Window window = new Window
{
Content = new TabControl
{
Items = new[]
{
//new TabItem
//{
// Header = "Buttons",
// Content = new StackPanel
// {
// Orientation = Orientation.Vertical,
// HorizontalAlignment = HorizontalAlignment.Center,
// VerticalAlignment = VerticalAlignment.Center,
// Gap = 8,
// MinWidth = 120,
// Children = new Controls
// {
// new Button
// {
// Content = "Button",
// },
// new Button
// {
// Content = "Button",
// Background = new SolidColorBrush(0xcc119eda),
// },
// new CheckBox
// {
// Content = "Checkbox",
// },
// }
// },
//},
//new TabItem
//{
// Header = "Text",
// Content = new StackPanel
// {
// Orientation = Orientation.Vertical,
// HorizontalAlignment = HorizontalAlignment.Center,
// VerticalAlignment = VerticalAlignment.Center,
// Gap = 8,
// Width = 120,
// Children = new Controls
// {
// new TextBlock
// {
// Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis dui quis libero suscipit tincidunt.",
// },
// new TextBox
// {
// Text = "Text Box",
// },
// }
// },
//},
//new TabItem
//{
// Header = "Images",
// Content = new StackPanel
// {
// Orientation = Orientation.Vertical,
// HorizontalAlignment = HorizontalAlignment.Center,
// VerticalAlignment = VerticalAlignment.Center,
// Gap = 8,
// Width = 120,
// Children = new Controls
// {
// new Image
// {
// Source = new Bitmap("github_icon.png"),
// Width = 200,
// },
// }
// },
//},
new TabItem
{
Header = "Buttons",
Content = new StackPanel
{
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Gap = 8,
MinWidth = 120,
Children = new Controls
{
new Button
{
Content = "Button",
},
new Button
{
Content = "Button",
Background = new SolidColorBrush(0xcc119eda),
},
new CheckBox
{
Content = "Checkbox",
},
}
},
},
new TabItem
{
Header = "Text",
Content = new StackPanel
{
Orientation = Orientation.Vertical,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
Gap = 8,
Width = 120,
Children = new Controls
{
new TextBlock
{
Text = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Proin venenatis dui quis libero suscipit tincidunt.",
},
new TextBox
{
Text = "Text Box",
},
}
},
},
new TabItem
{
Header = "Images",
Header = "Lists",
Content = new StackPanel
{
Orientation = Orientation.Vertical,
@ -107,10 +181,9 @@ namespace TestApplication
Width = 120,
Children = new Controls
{
new Image
new TreeView
{
Source = new Bitmap("github_icon.png"),
Width = 200,
Items = treeData,
},
}
},

Loading…
Cancel
Save