-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
/
AutoDataTemplateBindingHook.cs
77 lines (66 loc) · 2.71 KB
/
AutoDataTemplateBindingHook.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
// Copyright (c) 2023 .NET Foundation and Contributors. All rights reserved.
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.
// See the LICENSE file in the project root for full license information.
#if HAS_WINUI
using System;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using Microsoft.UI.Xaml.Markup;
namespace ReactiveUI
{
/// <summary>
/// AutoDataTemplateBindingHook is a binding hook that checks ItemsControls
/// that don't have DataTemplates, and assigns a default DataTemplate that
/// loads the View associated with each ViewModel.
/// </summary>
public class AutoDataTemplateBindingHook : IPropertyBindingHook
{
/// <summary>
/// Gets the default item template.
/// </summary>
public static Lazy<DataTemplate> DefaultItemTemplate { get; } = new(() =>
{
const string template = "<DataTemplate xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' " +
"xmlns:xaml='clr-namespace:ReactiveUI'>" +
"<xaml:ViewModelViewHost ViewModel=\"{Binding Mode=OneWay}\" VerticalContentAlignment=\"Stretch\" HorizontalContentAlignment=\"Stretch\" IsTabStop=\"False\" />" +
"</DataTemplate>";
return (DataTemplate)XamlReader.Load(template);
});
/// <inheritdoc/>
public bool ExecuteHook(object? source, object target, Func<IObservedChange<object, object>[]> getCurrentViewModelProperties, Func<IObservedChange<object, object>[]> getCurrentViewProperties, BindingDirection direction)
{
if (getCurrentViewProperties is null)
{
throw new ArgumentNullException(nameof(getCurrentViewProperties));
}
var viewProperties = getCurrentViewProperties();
var lastViewProperty = viewProperties.LastOrDefault();
if (lastViewProperty?.Sender is not ItemsControl itemsControl)
{
return true;
}
if (!string.IsNullOrEmpty(itemsControl.DisplayMemberPath))
{
return true;
}
if (viewProperties.Last().GetPropertyName() != "ItemsSource")
{
return true;
}
if (itemsControl.ItemTemplate is not null)
{
return true;
}
if (itemsControl.ItemTemplateSelector is not null)
{
return true;
}
itemsControl.ItemTemplate = DefaultItemTemplate.Value;
return true;
}
}
}
#endif