19 changed files with 665 additions and 322 deletions
@ -0,0 +1,16 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="IReadOnlyPerspexList.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex |
||||
|
{ |
||||
|
using System.Collections.Generic; |
||||
|
using System.Collections.Specialized; |
||||
|
using System.ComponentModel; |
||||
|
|
||||
|
public interface IReadOnlyPerspexList<T> : IReadOnlyList<T>, INotifyCollectionChanged, INotifyPropertyChanged |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,62 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="DataTemplateExtensions.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls |
||||
|
{ |
||||
|
using System.Linq; |
||||
|
using Splat; |
||||
|
|
||||
|
public static class DataTemplateExtensions |
||||
|
{ |
||||
|
public static Control ApplyDataTemplate(this Control control, object data) |
||||
|
{ |
||||
|
DataTemplate result = control.FindDataTemplate(data); |
||||
|
|
||||
|
if (result != null) |
||||
|
{ |
||||
|
return result.Build(data); |
||||
|
} |
||||
|
else if (data is Control) |
||||
|
{ |
||||
|
return (Control)data; |
||||
|
} |
||||
|
else |
||||
|
{ |
||||
|
return DataTemplate.Default.Build(data); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static DataTemplate FindDataTemplate(this Control control, object data) |
||||
|
{ |
||||
|
// TODO: This needs to traverse the logical tree, not the visual.
|
||||
|
foreach (var i in control.GetSelfAndVisualAncestors().OfType<Control>()) |
||||
|
{ |
||||
|
foreach (DataTemplate dt in i.DataTemplates.Reverse()) |
||||
|
{ |
||||
|
if (dt.Match(data)) |
||||
|
{ |
||||
|
return dt; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
IGlobalDataTemplates global = Locator.Current.GetService<IGlobalDataTemplates>(); |
||||
|
|
||||
|
if (global != null) |
||||
|
{ |
||||
|
foreach (DataTemplate dt in global.DataTemplates.Reverse()) |
||||
|
{ |
||||
|
if (dt.Match(data)) |
||||
|
{ |
||||
|
return dt; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,38 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="IItemContainerGenerator.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Generators |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
|
||||
|
public enum ItemContainerGeneratorState |
||||
|
{ |
||||
|
NoStarted, |
||||
|
Generating, |
||||
|
Generated, |
||||
|
} |
||||
|
|
||||
|
public interface IItemContainerGenerator |
||||
|
{ |
||||
|
event EventHandler StateChanged; |
||||
|
|
||||
|
ItemContainerGeneratorState State { get; } |
||||
|
|
||||
|
Control GetContainerForItem(object item); |
||||
|
|
||||
|
object GetItemForContainer(Control container); |
||||
|
|
||||
|
IEnumerable<Tuple<object, Control>> GetAll(); |
||||
|
|
||||
|
IEnumerable<Control> Generate(IEnumerable items); |
||||
|
|
||||
|
IEnumerable<Control> Remove(IEnumerable item); |
||||
|
|
||||
|
void RemoveAll(); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,126 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="ItemContainerGenerator.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Generators |
||||
|
{ |
||||
|
using System; |
||||
|
using System.Collections; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
|
||||
|
public class ItemContainerGenerator : IItemContainerGenerator |
||||
|
{ |
||||
|
private Dictionary<object, Control> containersByItem = new Dictionary<object, Control>(); |
||||
|
|
||||
|
private Dictionary<Control, object> itemsByContainer = new Dictionary<Control, object>(); |
||||
|
|
||||
|
private ItemContainerGeneratorState state; |
||||
|
|
||||
|
public ItemContainerGenerator(ItemsControl owner) |
||||
|
{ |
||||
|
this.Owner = owner; |
||||
|
} |
||||
|
|
||||
|
public event EventHandler StateChanged; |
||||
|
|
||||
|
public ItemContainerGeneratorState State |
||||
|
{ |
||||
|
get |
||||
|
{ |
||||
|
return this.state; |
||||
|
} |
||||
|
|
||||
|
set |
||||
|
{ |
||||
|
if (this.state != value) |
||||
|
{ |
||||
|
this.state = value; |
||||
|
|
||||
|
if (this.StateChanged != null) |
||||
|
{ |
||||
|
this.StateChanged(this, EventArgs.Empty); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
protected ItemsControl Owner |
||||
|
{ |
||||
|
get; |
||||
|
private set; |
||||
|
} |
||||
|
|
||||
|
public Control GetContainerForItem(object item) |
||||
|
{ |
||||
|
Control result; |
||||
|
this.containersByItem.TryGetValue(item, out result); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public object GetItemForContainer(Control container) |
||||
|
{ |
||||
|
object result; |
||||
|
this.itemsByContainer.TryGetValue(container, out result); |
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
public IEnumerable<Tuple<object, Control>> GetAll() |
||||
|
{ |
||||
|
return this.containersByItem.Select(x => Tuple.Create(x.Key, x.Value)); |
||||
|
} |
||||
|
|
||||
|
IEnumerable<Control> IItemContainerGenerator.Generate(IEnumerable items) |
||||
|
{ |
||||
|
List<Control> result = new List<Control>(); |
||||
|
|
||||
|
this.State = ItemContainerGeneratorState.Generating; |
||||
|
|
||||
|
try |
||||
|
{ |
||||
|
foreach (object item in items) |
||||
|
{ |
||||
|
Control container = this.CreateContainerOverride(item); |
||||
|
container.TemplatedParent = null; |
||||
|
this.containersByItem.Add(item, container); |
||||
|
this.itemsByContainer.Add(container, item); |
||||
|
result.Add(container); |
||||
|
} |
||||
|
} |
||||
|
finally |
||||
|
{ |
||||
|
this.State = ItemContainerGeneratorState.Generated; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
IEnumerable<Control> IItemContainerGenerator.Remove(IEnumerable items) |
||||
|
{ |
||||
|
List<Control> result = new List<Control>(); |
||||
|
|
||||
|
foreach (var item in items) |
||||
|
{ |
||||
|
Control container = this.containersByItem[item]; |
||||
|
this.containersByItem.Remove(item); |
||||
|
this.itemsByContainer.Remove(container); |
||||
|
result.Add(container); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
void IItemContainerGenerator.RemoveAll() |
||||
|
{ |
||||
|
this.containersByItem.Clear(); |
||||
|
this.itemsByContainer.Clear(); |
||||
|
} |
||||
|
|
||||
|
protected virtual Control CreateContainerOverride(object item) |
||||
|
{ |
||||
|
return this.Owner.ApplyDataTemplate(item); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,56 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="TreeItemContainerGenerator.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Generators |
||||
|
{ |
||||
|
public class TreeItemContainerGenerator<T> : ItemContainerGenerator where T : TreeViewItem, new() |
||||
|
{ |
||||
|
public TreeItemContainerGenerator(ItemsControl owner) |
||||
|
: base(owner) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected override Control CreateContainerOverride(object item) |
||||
|
{ |
||||
|
T result = item as T; |
||||
|
|
||||
|
if (result == null) |
||||
|
{ |
||||
|
TreeDataTemplate template = this.GetTreeDataTemplate(item); |
||||
|
|
||||
|
System.Diagnostics.Debug.WriteLine("{0} created item for {1}", this.GetHashCode(), item); |
||||
|
|
||||
|
result = new T |
||||
|
{ |
||||
|
Header = template.Build(item), |
||||
|
Items = template.ItemsSelector(item), |
||||
|
IsExpanded = template.IsExpanded(item), |
||||
|
}; |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
|
||||
|
private TreeDataTemplate GetTreeDataTemplate(object item) |
||||
|
{ |
||||
|
DataTemplate template = this.Owner.FindDataTemplate(item); |
||||
|
|
||||
|
if (template == null) |
||||
|
{ |
||||
|
template = DataTemplate.Default; |
||||
|
} |
||||
|
|
||||
|
TreeDataTemplate treeTemplate = template as TreeDataTemplate; |
||||
|
|
||||
|
if (treeTemplate == null) |
||||
|
{ |
||||
|
treeTemplate = new TreeDataTemplate(template.Build, x => null); |
||||
|
} |
||||
|
|
||||
|
return treeTemplate; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,29 @@ |
|||||
|
// -----------------------------------------------------------------------
|
||||
|
// <copyright file="TypedItemContainerGenerator.cs" company="Steven Kirk">
|
||||
|
// Copyright 2014 MIT Licence. See licence.md for more information.
|
||||
|
// </copyright>
|
||||
|
// -----------------------------------------------------------------------
|
||||
|
|
||||
|
namespace Perspex.Controls.Generators |
||||
|
{ |
||||
|
public class TypedItemContainerGenerator<T> : ItemContainerGenerator where T : ContentControl, new() |
||||
|
{ |
||||
|
public TypedItemContainerGenerator(ItemsControl owner) |
||||
|
: base(owner) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
protected override Control CreateContainerOverride(object item) |
||||
|
{ |
||||
|
T result = item as T; |
||||
|
|
||||
|
if (result == null) |
||||
|
{ |
||||
|
result = new T(); |
||||
|
result.Content = this.Owner.ApplyDataTemplate(item); |
||||
|
} |
||||
|
|
||||
|
return result; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue