Browse Source

Fix DataContexts.

This makes it so that IControls are no longer DataTemplate-able,
breaking TabControl. Need to find a better way.
pull/209/head
Steven Kirk 11 years ago
parent
commit
c4cfd967dc
  1. 9
      src/Perspex.Controls/Generators/ItemContainerGenerator.cs
  2. 18
      src/Perspex.Controls/Generators/ItemContainerGenerator`1.cs
  3. 2
      src/Perspex.Controls/Presenters/ContentPresenter.cs
  4. 41
      src/Perspex.Controls/Templates/DataTemplateExtensions.cs
  5. 44
      tests/Perspex.Controls.UnitTests/ItemsControlTests.cs

9
src/Perspex.Controls/Generators/ItemContainerGenerator.cs

@ -142,14 +142,7 @@ namespace Perspex.Controls.Generators
/// <returns>The created container control.</returns> /// <returns>The created container control.</returns>
protected virtual IControl CreateContainer(object item) protected virtual IControl CreateContainer(object item)
{ {
if (item == null) return Owner.MaterializeDataTemplate(item);
{
return null;
}
else
{
return Owner.MaterializeDataTemplate(item);
}
} }
/// <summary> /// <summary>

18
src/Perspex.Controls/Generators/ItemContainerGenerator`1.cs

@ -23,15 +23,23 @@ namespace Perspex.Controls.Generators
/// <inheritdoc/> /// <inheritdoc/>
protected override IControl CreateContainer(object item) protected override IControl CreateContainer(object item)
{ {
T result = item as T; var container = item as T;
if (result == null) if (item == null)
{ {
result = new T(); return null;
}
else if (container != null)
{
return container;
}
else
{
var result = new T();
result.Content = Owner.MaterializeDataTemplate(item); result.Content = Owner.MaterializeDataTemplate(item);
result.DataContext = item;
return result;
} }
return result;
} }
} }
} }

2
src/Perspex.Controls/Presenters/ContentPresenter.cs

@ -97,7 +97,7 @@ namespace Perspex.Controls.Presenters
{ {
var old = Child; var old = Child;
var content = Content; var content = Content;
var result = content != null ? this.MaterializeDataTemplate(content) : null; var result = this.MaterializeDataTemplate(content);
var logicalHost = this.FindReparentingHost(); var logicalHost = this.FindReparentingHost();
var logicalChildren = logicalHost?.LogicalChildren ?? LogicalChildren; var logicalChildren = logicalHost?.LogicalChildren ?? LogicalChildren;

41
src/Perspex.Controls/Templates/DataTemplateExtensions.cs

@ -19,28 +19,37 @@ namespace Perspex.Controls.Templates
/// <returns>The data materialized as a control.</returns> /// <returns>The data materialized as a control.</returns>
public static IControl MaterializeDataTemplate(this IControl control, object data) public static IControl MaterializeDataTemplate(this IControl control, object data)
{ {
IDataTemplate template = control.FindDataTemplate(data); if (data == null)
IControl result;
if (template != null)
{ {
result = template.Build(data); return null;
}
else
{
var asControl = data as IControl;
if (result != null && result.DataContext == null) if (asControl != null)
{
return asControl;
}
else
{ {
IDataTemplate template = control.FindDataTemplate(data);
IControl result;
if (template != null)
{
result = template.Build(data);
}
else
{
result = DataTemplate.Default.Build(data);
}
result.DataContext = data; result.DataContext = data;
return result;
} }
} }
else if (data is IControl)
{
result = (IControl)data;
}
else
{
result = DataTemplate.Default.Build(data);
}
return result;
} }
/// <summary> /// <summary>

44
tests/Perspex.Controls.UnitTests/ItemsControlTests.cs

@ -287,6 +287,50 @@ namespace Perspex.Controls.UnitTests
Assert.Equal(target, ((ILogical)child).LogicalParent); Assert.Equal(target, ((ILogical)child).LogicalParent);
} }
[Fact]
public void DataContexts_Should_Be_Correctly_Set()
{
var items = new object[]
{
"Foo",
new Item("Bar"),
new TextBlock { Text = "Baz" },
new ListBoxItem { Content = "Qux" },
};
var target = new ItemsControl
{
Template = GetTemplate(),
DataContext = "Base",
DataTemplates = new DataTemplates
{
new DataTemplate<Item>(x => new Button { Content = x })
},
Items = items,
};
target.ApplyTemplate();
var dataContexts = target.Presenter.Panel.Children
.Cast<Control>()
.Select(x => x.DataContext)
.ToList();
Assert.Equal(
new object[] { items[0], items[1], "Base", "Base" },
dataContexts);
}
private class Item
{
public Item(string value)
{
Value = value;
}
public string Value { get; }
}
private ControlTemplate GetTemplate() private ControlTemplate GetTemplate()
{ {
return new ControlTemplate<ItemsControl>(parent => return new ControlTemplate<ItemsControl>(parent =>

Loading…
Cancel
Save