diff --git a/Perspex.Controls/Deck.cs b/Perspex.Controls/Deck.cs
new file mode 100644
index 0000000000..71497eac31
--- /dev/null
+++ b/Perspex.Controls/Deck.cs
@@ -0,0 +1,44 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Controls
+{
+ using System.Collections;
+ using Perspex.Controls.Generators;
+ using Perspex.Controls.Primitives;
+ using Perspex.Controls.Utils;
+
+ ///
+ /// A selecting items control that displays a single item that fills the control.
+ ///
+ public class Deck : SelectingItemsControl
+ {
+ private static readonly ItemsPanelTemplate PanelTemplate =
+ new ItemsPanelTemplate(() => new Panel());
+
+ static Deck()
+ {
+ ItemsPanelProperty.OverrideDefaultValue(typeof(Deck), PanelTemplate);
+ }
+
+ protected override ItemContainerGenerator CreateItemContainerGenerator()
+ {
+ return new TypedItemContainerGenerator(this);
+ }
+
+ protected override void ItemsChanged(IEnumerable oldValue, IEnumerable newValue)
+ {
+ base.ItemsChanged(oldValue, newValue);
+
+ var items = this.Items;
+
+ if (items != null && items.Count() > 0)
+ {
+ this.SelectedIndex = 0;
+ }
+ }
+ }
+}
diff --git a/Perspex.Controls/DeckItem.cs b/Perspex.Controls/DeckItem.cs
new file mode 100644
index 0000000000..4def87b526
--- /dev/null
+++ b/Perspex.Controls/DeckItem.cs
@@ -0,0 +1,25 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Controls
+{
+ public class DeckItem : ContentControl, ISelectable
+ {
+ public static readonly PerspexProperty IsSelectedProperty =
+ PerspexProperty.Register("IsSelected");
+
+ static DeckItem()
+ {
+ Control.PseudoClass(IsSelectedProperty, ":selected");
+ }
+
+ public bool IsSelected
+ {
+ get { return this.GetValue(IsSelectedProperty); }
+ set { this.SetValue(IsSelectedProperty, value); }
+ }
+ }
+}
diff --git a/Perspex.Controls/Perspex.Controls.csproj b/Perspex.Controls/Perspex.Controls.csproj
index 360d044f75..a21f9cc112 100644
--- a/Perspex.Controls/Perspex.Controls.csproj
+++ b/Perspex.Controls/Perspex.Controls.csproj
@@ -41,6 +41,8 @@
+
+
diff --git a/Perspex.Themes.Default/DeckItemStyle.cs b/Perspex.Themes.Default/DeckItemStyle.cs
new file mode 100644
index 0000000000..c60382f374
--- /dev/null
+++ b/Perspex.Themes.Default/DeckItemStyle.cs
@@ -0,0 +1,38 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Themes.Default
+{
+ using Perspex.Controls;
+ using Perspex.Controls.Presenters;
+ using Perspex.Styling;
+ using System.Linq;
+
+ public class DeckItemStyle : Styles
+ {
+ public DeckItemStyle()
+ {
+ this.AddRange(new[]
+ {
+ new Style(x => x.OfType())
+ {
+ Setters = new[]
+ {
+ new Setter(DeckItem.TemplateProperty, ControlTemplate.Create(this.Template)),
+ },
+ },
+ });
+ }
+
+ private Control Template(DeckItem control)
+ {
+ return new ContentPresenter
+ {
+ [~ContentPresenter.ContentProperty] = control[~DeckItem.ContentProperty],
+ };
+ }
+ }
+}
diff --git a/Perspex.Themes.Default/DeckStyle.cs b/Perspex.Themes.Default/DeckStyle.cs
new file mode 100644
index 0000000000..07494599e3
--- /dev/null
+++ b/Perspex.Themes.Default/DeckStyle.cs
@@ -0,0 +1,54 @@
+// -----------------------------------------------------------------------
+//
+// Copyright 2015 MIT Licence. See licence.md for more information.
+//
+// -----------------------------------------------------------------------
+
+namespace Perspex.Themes.Default
+{
+ using Perspex.Controls;
+ using Perspex.Controls.Presenters;
+ using Perspex.Styling;
+ using System.Linq;
+
+ public class DeckStyle : Styles
+ {
+ public DeckStyle()
+ {
+ this.AddRange(new[]
+ {
+ new Style(x => x.OfType())
+ {
+ Setters = new[]
+ {
+ new Setter(Deck.TemplateProperty, ControlTemplate.Create(this.Template)),
+ },
+ },
+ new Style(x => x.OfType().Descendent().Is())
+ {
+ Setters = new[]
+ {
+ new Setter(Control.IsVisibleProperty, false),
+ },
+ },
+ new Style(x => x.OfType().Descendent().Is().Class(":selected"))
+ {
+ Setters = new[]
+ {
+ new Setter(Control.IsVisibleProperty, true),
+ },
+ }
+ });
+ }
+
+ private Control Template(Deck control)
+ {
+ return new ItemsPresenter
+ {
+ Id = "itemsPresenter",
+ [~ItemsPresenter.ItemsProperty] = control[~Deck.ItemsProperty],
+ [~ItemsPresenter.ItemsPanelProperty] = control[~Deck.ItemsPanelProperty],
+ };
+ }
+ }
+}
diff --git a/Perspex.Themes.Default/DefaultTheme.cs b/Perspex.Themes.Default/DefaultTheme.cs
index d85bef9421..59d3b208e3 100644
--- a/Perspex.Themes.Default/DefaultTheme.cs
+++ b/Perspex.Themes.Default/DefaultTheme.cs
@@ -22,6 +22,8 @@ namespace Perspex.Themes.Default
this.Add(new ItemsControlStyle());
this.Add(new ListBoxStyle());
this.Add(new ListBoxItemStyle());
+ this.Add(new DeckStyle());
+ this.Add(new DeckItemStyle());
this.Add(new PopupRootStyle());
this.Add(new RadioButtonStyle());
this.Add(new ScrollBarStyle());
diff --git a/Perspex.Themes.Default/ListBoxItemStyle.cs b/Perspex.Themes.Default/ListBoxItemStyle.cs
index 974b455e86..d87f93e476 100644
--- a/Perspex.Themes.Default/ListBoxItemStyle.cs
+++ b/Perspex.Themes.Default/ListBoxItemStyle.cs
@@ -6,14 +6,11 @@
namespace Perspex.Themes.Default
{
- using System.Linq;
using Perspex.Controls;
- using Perspex.Layout;
+ using Perspex.Controls.Presenters;
using Perspex.Media;
- using Perspex.Controls.Shapes;
using Perspex.Styling;
- using Perspex.Controls.Presenters;
- using Perspex.Controls.Primitives;
+ using System.Linq;
public class ListBoxItemStyle : Styles
{
diff --git a/Perspex.Themes.Default/Perspex.Themes.Default.csproj b/Perspex.Themes.Default/Perspex.Themes.Default.csproj
index af2f6cdb10..ec57ba1004 100644
--- a/Perspex.Themes.Default/Perspex.Themes.Default.csproj
+++ b/Perspex.Themes.Default/Perspex.Themes.Default.csproj
@@ -72,6 +72,8 @@
+
+
diff --git a/TestApplication/Program.cs b/TestApplication/Program.cs
index c85160351b..82552bd2b9 100644
--- a/TestApplication/Program.cs
+++ b/TestApplication/Program.cs
@@ -106,8 +106,9 @@ namespace TestApplication
static void Main(string[] args)
{
- //LogManager.Enable(new TestLogger());
+ LogManager.Enable(new TestLogger());
//LogManager.Instance.LogLayoutMessages = true;
+ LogManager.Instance.LogPropertyMessages = true;
// The version of ReactiveUI currently included is for WPF and so expects a WPF
// dispatcher. This makes sure it's initialized.
@@ -176,14 +177,14 @@ namespace TestApplication
DevTools.Attach(window);
- var renderer = ((IRenderRoot)window).Renderer;
- var last = renderer.RenderCount;
- DispatcherTimer.Run(() =>
- {
- fps.Text = "FPS: " + (renderer.RenderCount - last);
- last = renderer.RenderCount;
- return true;
- }, TimeSpan.FromSeconds(1));
+ //var renderer = ((IRenderRoot)window).Renderer;
+ //var last = renderer.RenderCount;
+ //DispatcherTimer.Run(() =>
+ //{
+ // fps.Text = "FPS: " + (renderer.RenderCount - last);
+ // last = renderer.RenderCount;
+ // return true;
+ //}, TimeSpan.FromSeconds(1));
window.Show();
Application.Current.Run(window);
@@ -383,6 +384,8 @@ namespace TestApplication
private static TabItem ListsTab()
{
+ ListBox listBox;
+
return new TabItem
{
Header = "Lists",
@@ -411,10 +414,16 @@ namespace TestApplication
Id = "treeView",
Items = treeData,
},
- new ListBox
+ (listBox = new ListBox
{
Items = listBoxData,
+ SelectedIndex = 0,
MaxHeight = 300,
+ }),
+ new Deck
+ {
+ Items = listBoxData,
+ [!Deck.SelectedItemProperty] = listBox[!ListBox.SelectedItemProperty],
},
new DropDown
{
@@ -565,20 +574,20 @@ namespace TestApplication
}
};
- var start = Animate.Stopwatch.Elapsed;
- var degrees = Animate.Timer
- .Select(x =>
- {
- var elapsed = (x - start).TotalSeconds;
- var cycles = elapsed / 4;
- var progress = cycles % 1;
- return 360.0 * progress;
- });
-
- border1.RenderTransform.Bind(
- RotateTransform.AngleProperty,
- degrees,
- BindingPriority.Animation);
+ //var start = Animate.Stopwatch.Elapsed;
+ //var degrees = Animate.Timer
+ // .Select(x =>
+ // {
+ // var elapsed = (x - start).TotalSeconds;
+ // var cycles = elapsed / 4;
+ // var progress = cycles % 1;
+ // return 360.0 * progress;
+ // });
+
+ //border1.RenderTransform.Bind(
+ // RotateTransform.AngleProperty,
+ // degrees,
+ // BindingPriority.Animation);
return result;
}
diff --git a/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs b/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
index 63954d9569..0d280f30a0 100644
--- a/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
+++ b/Tests/Perspex.Controls.UnitTests/Primitives/SelectingItemsControlTests.cs
@@ -14,6 +14,24 @@ namespace Perspex.Controls.Primitives.UnitTests
public class SelectingItemsControlTests
{
+ [Fact]
+ public void SelectedIndex_Should_Initially_Be_Minus_1()
+ {
+ var items = new[]
+ {
+ new Item(),
+ new Item(),
+ };
+
+ var target = new Target
+ {
+ Items = items,
+ Template = this.Template(),
+ };
+
+ Assert.Equal(-1, target.SelectedIndex);
+ }
+
[Fact]
public void Item_IsSelected_Should_Initially_Be_False()
{