Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Proposal of an extended Demo App #3825

Draft
wants to merge 6 commits into
base: develop
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
34 changes: 34 additions & 0 deletions src/MahApps.Metro.Demo_v2/App.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<Application x:Class="MahApps.Metro.Demo_v2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:avalon="http://icsharpcode.net/sharpdevelop/avalonedit"
xmlns:local="clr-namespace:MahApps.Metro.Demo_v2"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Blue.xaml" />

<!-- DemoView -->
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro.Demo_v2;component/Themes/DemoView.xaml" />
</ResourceDictionary.MergedDictionaries>

<Style BasedOn="{StaticResource {x:Type avalon:TextArea}}" TargetType="{x:Type avalon:TextArea}">
<Setter Property="SelectionBorder">
<Setter.Value>
<Pen Brush="{DynamicResource MahApps.Brushes.Highlight}" Thickness="1" />
</Setter.Value>
</Setter>
<Setter Property="SelectionBrush">
<Setter.Value>
<SolidColorBrush Opacity="0.7" Color="{DynamicResource MahApps.Colors.Highlight}" />
</Setter.Value>
</Setter>
<Setter Property="SelectionForeground" Value="{DynamicResource MahApps.Brushes.IdealForeground}" />
</Style>

</ResourceDictionary>
</Application.Resources>
</Application>
15 changes: 15 additions & 0 deletions src/MahApps.Metro.Demo_v2/App.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// 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 more information.

using System.Windows;

namespace MahApps.Metro.Demo_v2
{
/// <summary>
/// Interaction logic for App.xaml
/// </summary>
public partial class App : Application
{
}
}
14 changes: 14 additions & 0 deletions src/MahApps.Metro.Demo_v2/AssemblyInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// 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 more information.

using System.Windows;

[assembly: ThemeInfo(
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
//(used if a resource is not found in the page,
// or application resource dictionaries)
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
//(used if a resource is not found in the page,
// app, or any theme specific resource dictionaries)
)]
103 changes: 103 additions & 0 deletions src/MahApps.Metro.Demo_v2/Controls/DemoView.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// 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 more information.

using ICSharpCode.AvalonEdit;
using MahApps.Demo.Core;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;

namespace MahApps.Demo.Controls
{
[TemplatePart(Name = nameof(PART_AvalonEdit), Type = typeof(TextEditor))]
public class DemoView : HeaderedContentControl
{
private TextEditor PART_AvalonEdit;

/// <summary>Identifies the <see cref="ExampleXaml"/> dependency property.</summary>
public static readonly DependencyProperty ExampleXamlProperty = DependencyProperty.Register(nameof(ExampleXaml), typeof(string), typeof(DemoView), new PropertyMetadata(null, OnExampleXamlChanged));

/// <summary>Identifies the <see cref="HyperlinkOnlineDocs"/> dependency property.</summary>
public static readonly DependencyProperty HyperlinkOnlineDocsProperty = DependencyProperty.Register(nameof(HyperlinkOnlineDocs), typeof(string), typeof(DemoView), new PropertyMetadata(null));

public DemoView()
{
this.DemoProperties.CollectionChanged += this.DemoProperties_CollectionChanged;
}

public ObservableCollection<DemoViewProperty> DemoProperties { get; } = new ObservableCollection<DemoViewProperty>();

private void DemoProperties_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
if (e.NewItems != null)
{
foreach (DemoViewProperty item in e.NewItems)
{
item.PropertyChanged += this.DemoProperties_ItemPropertyChanged;
}
}

if (e.OldItems != null)
{
foreach (DemoViewProperty item in e.OldItems)
{
item.PropertyChanged -= this.DemoProperties_ItemPropertyChanged;
}
}
}

private void DemoProperties_ItemPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
this.SetExampleXaml();
}

public string ExampleXaml
{
get => (string)this.GetValue(ExampleXamlProperty);
set => this.SetValue(ExampleXamlProperty, value);
}

private void SetExampleXaml()
{
if (this.PART_AvalonEdit != null)
{
var exampleText = this.ExampleXaml;

foreach (var item in this.DemoProperties)
{
exampleText = exampleText.Replace($"[{item.PropertyName}]", item.GetExampleXamlContent());
}

this.PART_AvalonEdit.Text = exampleText;
}
}

private static void OnExampleXamlChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DemoView demoView)
{
demoView.SetExampleXaml();
}
}

public string HyperlinkOnlineDocs
{
get => (string)this.GetValue(HyperlinkOnlineDocsProperty);
set => this.SetValue(HyperlinkOnlineDocsProperty, value);
}

public SimpleCommand NavigateToOnlineDocs { get; } = new SimpleCommand(
(param) => !string.IsNullOrEmpty(param?.ToString()),
(param) => Process.Start(new ProcessStartInfo(param?.ToString())));

public override void OnApplyTemplate()
{
base.OnApplyTemplate();

this.PART_AvalonEdit = this.GetTemplateChild(nameof(this.PART_AvalonEdit)) as TextEditor;
this.SetExampleXaml();
}
}
}
207 changes: 207 additions & 0 deletions src/MahApps.Metro.Demo_v2/Controls/DemoViewProperty.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
// 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 more information.

using MahApps.Metro.Demo_v2;
using System;
using System.Collections;
using System.ComponentModel;
using System.Windows;
using System.Windows.Data;

namespace MahApps.Demo.Controls
{
public class DemoViewProperty : DependencyObject, INotifyPropertyChanged
{
#region PropertyChanged

public event PropertyChangedEventHandler PropertyChanged;

public void RaisePropertyChanged(string PropertyName)
{
this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
}

private static void OnValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is DemoViewProperty demoViewProperty)
{
demoViewProperty.RaisePropertyChanged(e.Property.Name);
}
}

#endregion

#region Constructors

public DemoViewProperty()
{
this.GetExampleXamlContent = this.GetExampleXamlContent_Default;
}

public DemoViewProperty(DependencyProperty dependencyProperty, DependencyObject bindingTarget, string groupName = null, DataTemplate dataTemplate = null)
: this()
{
this.SetCurrentValue(PropertyNameProperty, this.GetDefaultPropertyName(dependencyProperty));

this.SetCurrentValue(GroupNameProperty, groupName ?? this.GetDefaultGroupName());

this.SetCurrentValue(DataTemplateProperty, dataTemplate ?? this.GetDefaultDataTemplate(dependencyProperty));

// Create Binding to the Control
var binding = new Binding()
{
Path = new PropertyPath(dependencyProperty),
Source = bindingTarget,
Mode = BindingMode.TwoWay
};
BindingOperations.SetBinding(this, ValueProperty, binding);
}

#endregion

/// <summary>Identifies the <see cref="PropertyName"/> dependency property.</summary>
public static readonly DependencyProperty PropertyNameProperty = DependencyProperty.Register(nameof(PropertyName), typeof(string), typeof(DemoViewProperty), new PropertyMetadata(null));

/// <summary>Identifies the <see cref="Value"/> dependency property.</summary>
public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(nameof(Value), typeof(object), typeof(DemoViewProperty), new PropertyMetadata(null, OnValueChanged));

/// <summary>Identifies the <see cref="DataTemplate"/> dependency property.</summary>
public static readonly DependencyProperty DataTemplateProperty = DependencyProperty.Register(nameof(DataTemplate), typeof(DataTemplate), typeof(DemoViewProperty), new PropertyMetadata(null));

/// <summary>Identifies the <see cref="ItemSource"/> dependency property.</summary>
public static readonly DependencyProperty ItemSourceProperty = DependencyProperty.Register(nameof(ItemSource), typeof(IEnumerable), typeof(DemoViewProperty), new PropertyMetadata(null));

/// <summary>Identifies the <see cref="GroupName"/> dependency property.</summary>
public static readonly DependencyProperty GroupNameProperty = DependencyProperty.Register(nameof(GroupName), typeof(string), typeof(DemoViewProperty), new PropertyMetadata(null));

/// <summary>
/// Gets or Sets the PropertyName
/// </summary>
public string PropertyName
{
get => (string)this.GetValue(PropertyNameProperty);
set => this.SetValue(PropertyNameProperty, value);
}

private string GetDefaultPropertyName(DependencyProperty dependencyProperty)
{
if (typeof(UIElement).IsAssignableFrom(dependencyProperty.OwnerType))
{
return dependencyProperty.Name;
}
else
{
return $"{dependencyProperty.OwnerType.Name}.{dependencyProperty.Name}";
}
}

/// <summary>
/// Gets or Sets the Value
/// </summary>
public object Value
{
get => (object)this.GetValue(ValueProperty);
set => this.SetValue(ValueProperty, value);
}

/// <summary>
/// Gets or Sets the GroupName
/// </summary>
public string GroupName
{
get => (string)this.GetValue(GroupNameProperty);
set => this.SetValue(GroupNameProperty, value);
}

private string GetDefaultGroupName()
{
if (string.IsNullOrWhiteSpace(this.PropertyName))
return null;

switch (this.PropertyName)
{
case string _ when this.PropertyName.EndsWith("Alignment"):
case string _ when this.PropertyName.EndsWith("Height"):
case string _ when this.PropertyName.EndsWith("Width"):
return "Layout";

default:
return "Misc";
}
}

/// <summary>
/// Gets or Sets the DataTemplate
/// </summary>
public DataTemplate DataTemplate
{
get => (DataTemplate)this.GetValue(DataTemplateProperty);
set => this.SetValue(DataTemplateProperty, value);
}

private DataTemplate GetDefaultDataTemplate(DependencyProperty dependencyProperty)
{
// Any Object
if (dependencyProperty.PropertyType == typeof(object)) return null;

// Numeric
if (dependencyProperty.PropertyType.IsAssignableFrom(typeof(sbyte)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(byte)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(short)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(ushort)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(int)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(uint)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(long)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(ulong)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(float)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(double)) ||
dependencyProperty.PropertyType.IsAssignableFrom(typeof(decimal)))
{
return Application.Current.Resources["MahDemo.DataTemplates.PropertyPresenter.Numeric"] as DataTemplate;
}

if (dependencyProperty.PropertyType.IsAssignableFrom(typeof(string)))
{
return Application.Current.Resources["MahDemo.DataTemplates.PropertyPresenter.String"] as DataTemplate;
}

if (dependencyProperty.PropertyType == typeof(bool))
{
return Application.Current.Resources["MahDemo.DataTemplates.PropertyPresenter.Boolean"] as DataTemplate;
}

if (dependencyProperty.PropertyType.IsEnum)
{
return Application.Current.Resources["MahDemo.DataTemplates.PropertyPresenter.Enum"] as DataTemplate;
}

if (dependencyProperty.PropertyType.IsAssignableFrom(typeof(Style)))
{
return Application.Current.Resources["MahDemo.DataTemplates.PropertyPresenter.Styles"] as DataTemplate;
}

return null;
}

/// <summary>
/// Gets or Sets the ItemSource used for selectable <see cref="Value"/>
/// </summary>
public IEnumerable ItemSource
{
get => (IEnumerable)this.GetValue(ItemSourceProperty);
set => this.SetValue(ItemSourceProperty, value);
}

#region XAML Replace Value

public Func<string> GetExampleXamlContent { get; set; }

private string GetExampleXamlContent_Default()
{
return this.Value?.ToString();
}

#endregion
}
}