Skip to content

Commit

Permalink
fix(combobox): PlaceholderText not displaying
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoy312 committed Aug 25, 2020
1 parent 8ef6ac4 commit c4c1109
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 19 deletions.
46 changes: 31 additions & 15 deletions src/Uno.UI/UI/Xaml/Controls/ComboBox/ComboBox.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,12 @@ public partial class ComboBox : ListViewBase // TODO: Selector
public event EventHandler<object> DropDownClosed;
public event EventHandler<object> DropDownOpened;

private bool _areItemTemplatesForwarded = false;

private IPopup _popup;
private Border _popupBorder;
private ContentPresenter _contentPresenter;
private TextBlock _placeholderTextBlock;
private ContentPresenter _headerContentPresenter;

/// <summary>
Expand Down Expand Up @@ -79,6 +82,7 @@ protected override void OnApplyTemplate()
_popup = this.GetTemplateChild("Popup") as IPopup;
_popupBorder = this.GetTemplateChild("PopupBorder") as Border;
_contentPresenter = this.GetTemplateChild("ContentPresenter") as ContentPresenter;
_placeholderTextBlock = this.GetTemplateChild("PlaceholderTextBlock") as TextBlock;

if (_popup is PopupBase popup)
{
Expand All @@ -93,18 +97,7 @@ protected override void OnApplyTemplate()

if (_contentPresenter != null)
{
_contentPresenter.SetBinding(
ContentPresenter.ContentTemplateProperty,
new Binding(new PropertyPath("ItemTemplate"), null)
{
RelativeSource = RelativeSource.TemplatedParent
});
_contentPresenter.SetBinding(
ContentPresenter.ContentTemplateSelectorProperty,
new Binding(new PropertyPath("ItemTemplateSelector"), null)
{
RelativeSource = RelativeSource.TemplatedParent
});
_contentPresenter.SynchronizeContentWithOuterTemplatedParent = false;

_contentPresenter.DataContextChanged += (snd, evt) =>
{
Expand Down Expand Up @@ -248,10 +241,11 @@ internal override void OnItemClicked(int clickedIndex)

private void UpdateContentPresenter()
{
if (_contentPresenter != null)
if (_contentPresenter == null) return;

if (SelectedItem != null)
{
var item = GetSelectionContent();

var itemView = item as _View;

if (itemView != null)
Expand All @@ -273,12 +267,34 @@ private void UpdateContentPresenter()
}

_contentPresenter.Content = item;

if (itemView != null && itemView.GetVisualTreeParent() != _contentPresenter)
{
// Item may have been put back in list, reattach it to _contentPresenter
_contentPresenter.AddChild(itemView);
}
if (!_areItemTemplatesForwarded)
{
SetContentPresenterBinding(ContentPresenter.ContentTemplateProperty, nameof(ItemTemplate));
SetContentPresenterBinding(ContentPresenter.ContentTemplateSelectorProperty, nameof(ItemTemplateSelector));

_areItemTemplatesForwarded = true;
}
}
else
{
_contentPresenter.Content = _placeholderTextBlock;
if (_areItemTemplatesForwarded)
{
_contentPresenter.ClearValue(ContentPresenter.ContentTemplateProperty);
_contentPresenter.ClearValue(ContentPresenter.ContentTemplateSelectorProperty);

_areItemTemplatesForwarded = false;
}
}

void SetContentPresenterBinding(DependencyProperty targetProperty, string sourcePropertyPath)
{
_contentPresenter.SetBinding(targetProperty, new Binding(sourcePropertyPath) { RelativeSource = RelativeSource.TemplatedParent });
}
}

Expand Down
26 changes: 22 additions & 4 deletions src/Uno.UI/UI/Xaml/Controls/ContentPresenter/ContentPresenter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ private void InitializeContentPresenter()
{
}

/// <summary>
/// Indicates if the content should inherit templated parent from the presenter, or its templated parent.
/// </summary>
/// <remarks>Clear this flag to let the control nested directly under this ContentPresenter to inherit the correct templated parent</remarks>
internal bool SynchronizeContentWithOuterTemplatedParent { get; set; } = true;

/// <summary>
/// Determines if the current ContentPresenter is hosting a native control.
/// </summary>
Expand Down Expand Up @@ -695,11 +701,23 @@ private void SynchronizeContentTemplatedParent()
{
if (_contentTemplateRoot is IFrameworkElement binder)
{
var templatedParent = _contentTemplateRoot is ImplicitTextBlock
? this // ImplicitTextBlock is a special case that requires its TemplatedParent to be the ContentPresenter
: (this.TemplatedParent as IFrameworkElement)?.TemplatedParent;
binder.TemplatedParent = FindTemplatedParent();

binder.TemplatedParent = templatedParent;
DependencyObject FindTemplatedParent()
{
// ImplicitTextBlock is a special case that requires its TemplatedParent to be the ContentPresenter
if (_contentTemplateRoot is ImplicitTextBlock) return this;

// Sometimes when content is a child view defined in the xaml, the direct TemplatedParent should be used,
// but only if the content hasnt been overwritten yet. If the content has been overwritten,
// either ImplicitTextBlock or the DataTemplate (requiring the outter TemplatedParent) would has been used.
if (!SynchronizeContentWithOuterTemplatedParent && _dataTemplateUsedLastUpdate == null)
{
return this.TemplatedParent;
}

return (this.TemplatedParent as IFrameworkElement)?.TemplatedParent;
}
}
else if (_contentTemplateRoot is DependencyObject dependencyObject)
{
Expand Down

0 comments on commit c4c1109

Please sign in to comment.