Browse Source

Make ItemsControl templated.

pull/4/head
Steven Kirk 12 years ago
parent
commit
f0339bf4b4
  1. 2
      Perspex/Controls/ControlTemplate.cs
  2. 2
      Perspex/Controls/DataTemplate.cs
  3. 63
      Perspex/Controls/ItemsControl.cs
  4. 99
      Perspex/Controls/ItemsPresenter.cs
  5. 2
      Perspex/Perspex.csproj
  6. 2
      Perspex/Themes/Default/DefaultTheme.cs
  7. 41
      Perspex/Themes/Default/ItemsControlStyle.cs

2
Perspex/Controls/ControlTemplate.cs

@ -7,8 +7,6 @@
namespace Perspex.Controls
{
using System;
using System.Linq;
using Perspex.Controls;
public class ControlTemplate
{

2
Perspex/Controls/DataTemplate.cs

@ -12,7 +12,7 @@ namespace Perspex.Controls
public class DataTemplate
{
public static readonly DataTemplate Default =
new DataTemplate(typeof(object), o => new TextBox { Text = o.ToString() });
new DataTemplate(typeof(object), o => new TextBlock { Text = o.ToString() });
public DataTemplate(Type type, Func<object, IVisual> build)
: this(o => type.GetTypeInfo().IsAssignableFrom(o.GetType().GetTypeInfo()), build)

63
Perspex/Controls/ItemsControl.cs

@ -6,13 +6,9 @@
namespace Perspex.Controls
{
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Perspex.Layout;
public class ItemsControl : Control, IVisual
public class ItemsControl : TemplatedControl
{
private static readonly ItemsPanelTemplate defaultPanel =
new ItemsPanelTemplate(() => new StackPanel { Orientation = Orientation.Vertical });
@ -23,11 +19,8 @@ namespace Perspex.Controls
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel", defaultValue: defaultPanel);
private Panel panel;
public ItemsControl()
{
this.GetObservable(ItemsProperty).Subscribe(this.ItemsChanged);
}
public IEnumerable Items
@ -41,59 +34,5 @@ namespace Perspex.Controls
get { return this.GetValue(ItemsPanelProperty); }
set { this.SetValue(ItemsPanelProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); }
}
IEnumerable<IVisual> IVisual.VisualChildren
{
get { return Enumerable.Repeat(this.GetPanel(), 1); }
}
protected override Size MeasureOverride(Size availableSize)
{
Panel panel = this.GetPanel();
panel.Measure(availableSize);
return panel.DesiredSize.Value;
}
protected override Size ArrangeOverride(Size finalSize)
{
this.GetPanel().Arrange(new Rect(finalSize));
return finalSize;
}
private IEnumerable<Control> CreateItems(IEnumerable items)
{
if (items != null)
{
return items
.Cast<object>()
.Select(x => this.GetDataTemplate(x).Build(x))
.OfType<Control>();
}
else
{
return Enumerable.Empty<Control>();
}
}
private Panel GetPanel()
{
if (this.panel == null)
{
this.panel = this.ItemsPanel.Build();
this.panel.Children = new PerspexList<Control>(this.CreateItems(this.Items));
}
return this.panel;
}
private void ItemsChanged(IEnumerable items)
{
this.GetPanel().Children = new PerspexList<Control>(this.CreateItems(items));
}
}
}

99
Perspex/Controls/ItemsPresenter.cs

@ -0,0 +1,99 @@
// -----------------------------------------------------------------------
// <copyright file="ItemsControl.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.Collections.Generic;
using System.Linq;
using Perspex.Layout;
public class ItemsPresenter : Control, IVisual
{
public static readonly PerspexProperty<IEnumerable> ItemsProperty =
PerspexProperty.Register<ItemsControl, IEnumerable>("Items");
public static readonly PerspexProperty<ItemsPanelTemplate> ItemsPanelProperty =
PerspexProperty.Register<ItemsControl, ItemsPanelTemplate>("ItemsPanel");
private Panel panel;
public ItemsPresenter()
{
this.GetObservable(ItemsProperty).Subscribe(this.ItemsChanged);
}
public IEnumerable Items
{
get { return this.GetValue(ItemsProperty); }
set { this.SetValue(ItemsProperty, value); }
}
public ItemsPanelTemplate ItemsPanel
{
get { return this.GetValue(ItemsPanelProperty); }
set { this.SetValue(ItemsPanelProperty, value); }
}
IEnumerable<IVisual> IVisual.ExistingVisualChildren
{
get { return Enumerable.Repeat(this.panel, this.panel != null ? 1 : 0); }
}
IEnumerable<IVisual> IVisual.VisualChildren
{
get { return Enumerable.Repeat(this.GetPanel(), 1); }
}
protected override Size MeasureOverride(Size availableSize)
{
Panel panel = this.GetPanel();
panel.Measure(availableSize);
return panel.DesiredSize.Value;
}
protected override Size ArrangeOverride(Size finalSize)
{
this.GetPanel().Arrange(new Rect(finalSize));
return finalSize;
}
private IEnumerable<Control> CreateItems(IEnumerable items)
{
if (items != null)
{
return items
.Cast<object>()
.Select(x => this.GetDataTemplate(x).Build(x))
.OfType<Control>();
}
else
{
return Enumerable.Empty<Control>();
}
}
private Panel GetPanel()
{
if (this.panel == null && this.ItemsPanel != null)
{
this.panel = this.ItemsPanel.Build();
this.ItemsChanged(this.Items);
}
return this.panel;
}
private void ItemsChanged(IEnumerable items)
{
if (this.panel != null)
{
this.panel.Children = new PerspexList<Control>(this.CreateItems(items));
}
}
}
}

2
Perspex/Perspex.csproj

@ -70,6 +70,7 @@
<ItemGroup>
<Compile Include="Application.cs" />
<Compile Include="BindingExtensions.cs" />
<Compile Include="Controls\ItemsPresenter.cs" />
<Compile Include="Controls\ItemsPanelTemplate.cs" />
<Compile Include="Controls\ItemsControl.cs" />
<Compile Include="Controls\DataTemplate.cs" />
@ -126,6 +127,7 @@
<Compile Include="Media\Geometry.cs" />
<Compile Include="Media\Stretch.cs" />
<Compile Include="Themes\Default\ContentControlStyle.cs" />
<Compile Include="Themes\Default\ItemsControlStyle.cs" />
<Compile Include="Vector.cs" />
<Compile Include="Rendering\RenderManager.cs" />
<Compile Include="Rendering\IRenderManager.cs" />

2
Perspex/Themes/Default/DefaultTheme.cs

@ -15,7 +15,9 @@ namespace Perspex.Themes.Default
this.Add(new ButtonStyle());
this.Add(new CheckBoxStyle());
this.Add(new ContentControlStyle());
this.Add(new ItemsControlStyle());
this.Add(new TextBoxStyle());
this.Add(new ItemsControlStyle());
}
}
}

41
Perspex/Themes/Default/ItemsControlStyle.cs

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