ContentControl doesn't update ControlTemplate when moved to another container (parent changes)
- Dominant language
- C#
- Stars
- 7.7k
- Forks
- 1.3k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 61
Description
* .NET Core Version: 5.0.301
* Windows version: 10 (20H2)
* Does the bug reproduce also in WPF for .NET Framework 4.8?: Yes
**Problem description:**
ContentControl doesn't update ControlTemplate when moved to another container (parent changes). Is it a bug or the correct action?
**Minimal repro:**
I have two StackPanels. Each of them has defined a DataTemplate of the same LineItem type. When I move ContentControl from one to the other container I suspect that the view of the items will change. But it doesn't happen.
Create "WPF App (.NET 5)" or "WPF App (.NET Framework)" project and override MainWindow files:
```xaml
```
```c#
namespace WpfApp7core
{
public class LineItem
{
public string Name { get; set; }
public string Value { get; set; }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Create1_Click(object sender, RoutedEventArgs e)
{
var li = new LineItem { Name = "Left", Value = Guid.NewGuid().ToString() };
column1.Children.Add(new ContentControl { Content = li });
}
private void Create2_Click(object sender, RoutedEventArgs e)
{
var li = new LineItem { Name = "Right", Value = Guid.NewGuid().ToString() };
column2.Children.Add(new ContentControl { Content = li });
}
private void MoveTo2_Click(object sender, RoutedEventArgs e)
{
foreach (FrameworkElement item in Enumerable.Range(0, column1.Children.Count).Select(i => column1.Children[i]).Cast().ToList())
{
RemoveFromParent(item); // Remove from column1
column2.Children.Add(item); // Add to column2
}
}
private void MoveTo1_Click(object sender, RoutedEventArgs e)
{
foreach (FrameworkElement item in Enumerable.Range(0, column2.Children.Count).Select(i => column2.Children[i]).Cast().ToList())
{
RemoveFromParent(item); // Remove from column2
column1.Children.Add(item); // Add to column1
}
}
public static void RemoveFromParent(FrameworkElement child)
{
switch (child.Parent)
{
case Panel panel: panel.Children.Remove(child); break;
case Decorator decorator: decorator.Child = null; break;
case ContentControl contentControl: contentControl.Content = null; break;
case ContentPresenter contentPresenter: contentPresenter.Content = null; break;
default: throw new Exception($"Unknown parent type {child.Parent.GetType()}");
}
}
}
}
```

**Expected behaviour:**
Each items on the left should be blue, and each on the right should be green.
**Unwanted solution:**
I found one solution. When I assign Content to null and then assign the previous value, ContentControl will update its view.
```c#
foreach (FrameworkElement item in Enumerable.Range(0, column1.Children.Count).Select(i => column1.Children[i]).Cast().ToList())
{
RemoveFromParent(item);
column2.Children.Add(item);
if (item is ContentControl cc)
{
var prev = cc.Content;
cc.Content = null;
cc.Content = prev;
}
}
```
But this solution becomes complicated when you have an extensive view tree.
Contributor guide
Assessment
This issue has not been assessed yet.