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>
protected virtual IControl CreateContainer(object item)
{
if (item == null)
{
return null;
}
else
{
return Owner.MaterializeDataTemplate(item);
}
return Owner.MaterializeDataTemplate(item);
}
/// <summary>

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

@ -23,15 +23,23 @@ namespace Perspex.Controls.Generators
/// <inheritdoc/>
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.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 content = Content;
var result = content != null ? this.MaterializeDataTemplate(content) : null;
var result = this.MaterializeDataTemplate(content);
var logicalHost = this.FindReparentingHost();
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>
public static IControl MaterializeDataTemplate(this IControl control, object data)
{
IDataTemplate template = control.FindDataTemplate(data);
IControl result;
if (template != null)
if (data == 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;
return result;
}
}
else if (data is IControl)
{
result = (IControl)data;
}
else
{
result = DataTemplate.Default.Build(data);
}
return result;
}
/// <summary>

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

@ -287,6 +287,50 @@ namespace Perspex.Controls.UnitTests
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()
{
return new ControlTemplate<ItemsControl>(parent =>

Loading…
Cancel
Save