mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-03-04 16:50:51 +08:00
622 lines
21 KiB
C#
622 lines
21 KiB
C#
#pragma warning disable SA1402 // File may only contain a single class
|
|
namespace FluentTest
|
|
{
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Diagnostics;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Reflection;
|
|
using System.Text;
|
|
using System.Threading;
|
|
using System.Threading.Tasks;
|
|
using System.Windows;
|
|
using System.Windows.Controls;
|
|
using System.Windows.Data;
|
|
using System.Windows.Input;
|
|
using System.Windows.Media;
|
|
using System.Windows.Media.Imaging;
|
|
using ControlzEx.Theming;
|
|
using Fluent;
|
|
using Fluent.Localization;
|
|
using FluentTest.Adorners;
|
|
using FluentTest.Helpers;
|
|
using FluentTest.ViewModels;
|
|
#if MahApps_Metro
|
|
using MahApps.Metro.Controls;
|
|
using MahApps.Metro.Controls.Dialogs;
|
|
#endif
|
|
using Button = Fluent.Button;
|
|
|
|
/// <summary>
|
|
/// Test-Content
|
|
/// </summary>
|
|
public partial class TestContent : UserControl
|
|
{
|
|
private readonly MainViewModel viewModel;
|
|
private string windowTitle;
|
|
|
|
public TestContent()
|
|
{
|
|
this.InitializeComponent();
|
|
|
|
//RibbonLocalization.Current.Localization.Culture = new CultureInfo("ru-RU");
|
|
|
|
this.HookEvents();
|
|
|
|
this.viewModel = new MainViewModel();
|
|
this.DataContext = this.viewModel;
|
|
|
|
ColorGallery.RecentColors.Add(((SolidColorBrush)Application.Current.Resources["Fluent.Ribbon.Brushes.AccentBaseColorBrush"]).Color);
|
|
|
|
this.Loaded += this.TestContent_Loaded;
|
|
}
|
|
|
|
public string WindowTitle => this.windowTitle ?? (this.windowTitle = GetVersionText(Window.GetWindow(this).GetType().BaseType));
|
|
|
|
#pragma warning disable WPF0060
|
|
/// <summary>Identifies the <see cref="Brushes"/> dependency property.</summary>
|
|
public static readonly DependencyProperty BrushesProperty = DependencyProperty.Register(nameof(Brushes), typeof(List<KeyValuePair<string, Brush>>), typeof(TestContent), new PropertyMetadata(default(List<KeyValuePair<string, Brush>>)));
|
|
#pragma warning restore WPF0060
|
|
|
|
public List<KeyValuePair<string, Brush>> Brushes
|
|
{
|
|
get { return (List<KeyValuePair<string, Brush>>)this.GetValue(BrushesProperty); }
|
|
set { this.SetValue(BrushesProperty, value); }
|
|
}
|
|
|
|
public List<RibbonLocalizationBase> Localizations { get; } = GetLocalizations();
|
|
|
|
private static List<RibbonLocalizationBase> GetLocalizations()
|
|
{
|
|
return RibbonLocalization.Current.LocalizationMap.Values
|
|
.Select(x => (RibbonLocalizationBase)Activator.CreateInstance(x))
|
|
.ToList();
|
|
}
|
|
|
|
private static IEnumerable<KeyValuePair<string, Brush>> GetBrushes()
|
|
{
|
|
var brushes = typeof(Brushes)
|
|
.GetProperties()
|
|
.Where(prop =>
|
|
typeof(Brush).IsAssignableFrom(prop.PropertyType))
|
|
.Select(prop =>
|
|
new KeyValuePair<string, Brush>(prop.Name, (Brush)prop.GetValue(null, null)));
|
|
return ThemeManager.Current.Themes.GroupBy(x => x.ColorScheme)
|
|
.Select(x => x.First())
|
|
.Select(x => new KeyValuePair<string, Brush>(x.ColorScheme, x.ShowcaseBrush))
|
|
.Concat(brushes)
|
|
.OrderBy(x => x.Key);
|
|
}
|
|
|
|
private static string GetVersionText(Type type)
|
|
{
|
|
var version = type.Assembly.GetName().Version;
|
|
|
|
var assemblyProductAttribute = type.Assembly.GetCustomAttribute<AssemblyProductAttribute>();
|
|
|
|
var assemblyInformationalVersionAttribute = type.Assembly.GetCustomAttribute<AssemblyInformationalVersionAttribute>();
|
|
|
|
return $"{assemblyProductAttribute?.Product} {version} ({assemblyInformationalVersionAttribute?.InformationalVersion})";
|
|
}
|
|
|
|
private string selectedMenu = "Backstage";
|
|
|
|
public string SelectedMenu
|
|
{
|
|
get => this.selectedMenu;
|
|
set
|
|
{
|
|
this.selectedMenu = value;
|
|
|
|
switch (this.selectedMenu)
|
|
{
|
|
case "ApplicationMenu":
|
|
this.ApplicationMenu.Visibility = Visibility.Visible;
|
|
this.Backstage.Visibility = Visibility.Collapsed;
|
|
break;
|
|
|
|
case "Backstage":
|
|
this.ApplicationMenu.Visibility = Visibility.Collapsed;
|
|
this.Backstage.Visibility = Visibility.Visible;
|
|
break;
|
|
|
|
case "Empty menu":
|
|
this.ApplicationMenu.Visibility = Visibility.Collapsed;
|
|
this.Backstage.Visibility = Visibility.Collapsed;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
private void HookEvents()
|
|
{
|
|
this.Loaded += this.HandleTestContentLoaded;
|
|
|
|
this.buttonBold.Checked += (s, e) => Debug.WriteLine("Checked");
|
|
this.buttonBold.Unchecked += (s, e) => Debug.WriteLine("Unchecked");
|
|
|
|
this.PreviewMouseWheel += this.OnPreviewMouseWheel;
|
|
}
|
|
|
|
private void TestContent_Loaded(object sender, RoutedEventArgs e)
|
|
{
|
|
this.Loaded -= this.TestContent_Loaded;
|
|
|
|
this.InitializeBrushes();
|
|
}
|
|
|
|
private void InitializeBrushes()
|
|
{
|
|
var currentBrushes = new[]
|
|
{
|
|
new KeyValuePair<string, Brush>("None", null),
|
|
new KeyValuePair<string, Brush>("Initial glow", GetCurrentGlowBrush()),
|
|
new KeyValuePair<string, Brush>("Initial non active glow", GetCurrentNonActiveGlowBrush()),
|
|
};
|
|
|
|
this.Brushes = currentBrushes.Concat(GetBrushes()).ToList();
|
|
|
|
Brush GetCurrentGlowBrush()
|
|
{
|
|
switch (Window.GetWindow(this))
|
|
{
|
|
case RibbonWindow x:
|
|
return x.GlowBrush;
|
|
#if MahApps_Metro
|
|
case MetroWindow x:
|
|
return x.GlowBrush;
|
|
#endif
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
Brush GetCurrentNonActiveGlowBrush()
|
|
{
|
|
switch (Window.GetWindow(this))
|
|
{
|
|
case RibbonWindow x:
|
|
return x.NonActiveGlowBrush;
|
|
#if MahApps_Metro
|
|
case MetroWindow x:
|
|
return x.NonActiveGlowBrush;
|
|
#endif
|
|
}
|
|
|
|
return null;
|
|
}
|
|
}
|
|
|
|
private static void OnScreenTipHelpPressed(object sender, ScreenTipHelpEventArgs e)
|
|
{
|
|
Process.Start((string)e.HelpTopic);
|
|
}
|
|
|
|
private void HandleTestContentLoaded(object sender, RoutedEventArgs e)
|
|
{
|
|
ScreenTip.HelpPressed += OnScreenTipHelpPressed;
|
|
}
|
|
|
|
private void OnLauncherButtonClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var groupBox = (RibbonGroupBox)sender;
|
|
|
|
var wnd = new Window
|
|
{
|
|
Content = $"Launcher-Window for: {groupBox.Header}",
|
|
Width = 300,
|
|
Height = 100,
|
|
Owner = Window.GetWindow(this),
|
|
WindowStartupLocation = WindowStartupLocation.CenterOwner
|
|
};
|
|
|
|
wnd.ShowDialog();
|
|
}
|
|
|
|
private void OnSplitClick(object sender, RoutedEventArgs e)
|
|
{
|
|
MessageBox.Show("Split Clicked!!!");
|
|
}
|
|
|
|
private void OnEnlargeClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if (this.InRibbonGallery.IsLoaded)
|
|
{
|
|
this.InRibbonGallery.Enlarge();
|
|
}
|
|
}
|
|
|
|
private void OnReduceClick(object sender, RoutedEventArgs e)
|
|
{
|
|
if (this.InRibbonGallery.IsLoaded)
|
|
{
|
|
this.InRibbonGallery.Reduce();
|
|
}
|
|
}
|
|
|
|
private void SyncThemeNow_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
ThemeManager.Current.SyncTheme();
|
|
}
|
|
|
|
public Button CreateRibbonButton()
|
|
{
|
|
var fooCommand1 = new TestRoutedCommand();
|
|
|
|
var button = new Button
|
|
{
|
|
Command = fooCommand1.ItemCommand,
|
|
Header = "Foo",
|
|
Icon = new BitmapImage(new Uri("pack://application:,,,/Fluent.Ribbon.Showcase;component/Images/Green.png", UriKind.Absolute)),
|
|
LargeIcon = new BitmapImage(new Uri("pack://application:,,,/Fluent.Ribbon.Showcase;component/Images/GreenLarge.png", UriKind.Absolute)),
|
|
};
|
|
|
|
this.CommandBindings.Add(fooCommand1.ItemCommandBinding);
|
|
return button;
|
|
}
|
|
|
|
#region Logical tree
|
|
|
|
private void OnShowLogicalTreeClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.CheckLogicalTree(this.ribbon);
|
|
this.logicalTreeView.Items.Clear();
|
|
this.BuildLogicalTree(this.ribbon, this.logicalTreeView);
|
|
}
|
|
|
|
private static string GetDebugInfo(DependencyObject element)
|
|
{
|
|
if (element is null)
|
|
{
|
|
return "NULL";
|
|
}
|
|
|
|
var debugInfo = $"[{element}]";
|
|
|
|
if (element is IHeaderedControl headeredControl)
|
|
{
|
|
debugInfo += $" Header: \"{headeredControl.Header}\"";
|
|
}
|
|
|
|
if (element is FrameworkElement frameworkElement
|
|
&& string.IsNullOrEmpty(frameworkElement.Name) == false)
|
|
{
|
|
debugInfo += $" Name: \"{frameworkElement.Name}\"";
|
|
}
|
|
|
|
return debugInfo;
|
|
}
|
|
|
|
private void CheckLogicalTree(DependencyObject root)
|
|
{
|
|
var children = LogicalTreeHelper.GetChildren(root);
|
|
foreach (var child in children.OfType<DependencyObject>())
|
|
{
|
|
if (ReferenceEquals(LogicalTreeHelper.GetParent(child), root) == false)
|
|
{
|
|
Debug.WriteLine($"Incorrect logical parent for {GetDebugInfo(child)}");
|
|
Debug.WriteLine($"\tExpected: {GetDebugInfo(root)}");
|
|
Debug.WriteLine($"\tFound: {GetDebugInfo(LogicalTreeHelper.GetParent(child))}");
|
|
}
|
|
|
|
this.CheckLogicalTree(child);
|
|
}
|
|
}
|
|
|
|
private void BuildLogicalTree(DependencyObject current, ItemsControl parentControl)
|
|
{
|
|
var newItem = new TreeViewItem
|
|
{
|
|
Header = GetDebugInfo(current),
|
|
Tag = current
|
|
};
|
|
|
|
parentControl.Items.Add(newItem);
|
|
|
|
var children = LogicalTreeHelper.GetChildren(current);
|
|
foreach (var child in children.OfType<DependencyObject>())
|
|
{
|
|
this.BuildLogicalTree(child, newItem);
|
|
}
|
|
}
|
|
|
|
private void OnTreeDoubleClick(object sender, MouseButtonEventArgs e)
|
|
{
|
|
var treeView = sender as TreeView;
|
|
|
|
var item = treeView?.SelectedItem as TreeViewItem;
|
|
if (item is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var stringBuilder = new StringBuilder();
|
|
this.BuildBackLogicalTree(item.Tag as DependencyObject, stringBuilder);
|
|
|
|
MessageBox.Show($"From buttom to top:\n{stringBuilder}");
|
|
}
|
|
|
|
private void BuildBackLogicalTree(DependencyObject current, StringBuilder stringBuilder)
|
|
{
|
|
if (current is null
|
|
|| ReferenceEquals(current, this.ribbon))
|
|
{
|
|
return;
|
|
}
|
|
|
|
stringBuilder.AppendFormat(" -> {0}\n", GetDebugInfo(current));
|
|
|
|
var parent = LogicalTreeHelper.GetParent(current);
|
|
|
|
this.BuildBackLogicalTree(parent, stringBuilder);
|
|
}
|
|
|
|
#endregion Logical tree
|
|
|
|
private void OnFormatPainterClick(object sender, RoutedEventArgs e)
|
|
{
|
|
MessageBox.Show("FP");
|
|
}
|
|
|
|
private void OnHelpClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.viewModel.AreContextGroupsVisible = !this.viewModel.AreContextGroupsVisible;
|
|
}
|
|
|
|
private void OnSpinnerValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
|
{
|
|
// MessageBox.Show(String.Format("Changed from {0} to {1}", e.OldValue, e.NewValue));
|
|
}
|
|
|
|
private void OnMenuItemClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var wnd = new TestWindow
|
|
{
|
|
Owner = Window.GetWindow(this)
|
|
};
|
|
wnd.Show();
|
|
}
|
|
|
|
private void AddRibbonTab_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var tab = new RibbonTabItem
|
|
{
|
|
Header = "Test"
|
|
};
|
|
|
|
var group = new RibbonGroupBox();
|
|
for (var i = 0; i < 20; i++)
|
|
{
|
|
group.Items.Add(this.CreateRibbonButton());
|
|
}
|
|
|
|
tab.Groups.Add(group);
|
|
|
|
this.ribbon.Tabs.Add(tab);
|
|
}
|
|
|
|
private async void HandleSaveAsClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var progressAdornerChild = new Border
|
|
{
|
|
VerticalAlignment = VerticalAlignment.Stretch,
|
|
HorizontalAlignment = HorizontalAlignment.Stretch,
|
|
Background = new SolidColorBrush(Colors.Black) { Opacity = 0.25 },
|
|
IsHitTestVisible = true,
|
|
Child = new ProgressBar
|
|
{
|
|
IsIndeterminate = true,
|
|
Width = 300,
|
|
Height = 20,
|
|
VerticalAlignment = VerticalAlignment.Center,
|
|
HorizontalAlignment = HorizontalAlignment.Center
|
|
}
|
|
};
|
|
BindingOperations.SetBinding(progressAdornerChild, WidthProperty, new Binding(nameof(this.Backstage.AdornerLayer.ActualWidth)) { Source = this.Backstage.AdornerLayer });
|
|
BindingOperations.SetBinding(progressAdornerChild, HeightProperty, new Binding(nameof(this.Backstage.AdornerLayer.ActualHeight)) { Source = this.Backstage.AdornerLayer });
|
|
|
|
var progressAdorner = new SimpleControlAdorner(this.Backstage.AdornerLayer)
|
|
{
|
|
Child = progressAdornerChild
|
|
};
|
|
|
|
this.Backstage.AdornerLayer.Add(progressAdorner);
|
|
|
|
await Task.Delay(TimeSpan.FromSeconds(3));
|
|
|
|
this.Backstage.AdornerLayer.Remove(progressAdorner);
|
|
|
|
BindingOperations.ClearAllBindings(progressAdornerChild);
|
|
}
|
|
|
|
private void OpenRegularWindow_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new RegularWindow().Show();
|
|
}
|
|
|
|
private void OpenMinimalRibbonWindowSample_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new MinimalWindowSample().Show();
|
|
}
|
|
|
|
private void OpenMahMetroWindow_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
#if MahApps_Metro
|
|
new MahMetroWindow().Show();
|
|
#else
|
|
ShowMahAppsMetroNotAvailableMessageBox();
|
|
#endif
|
|
}
|
|
|
|
private void OpenRibbonWindowWithoutVisibileRibbon_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new RibbonWindowWithoutVisibleRibbon().Show();
|
|
}
|
|
|
|
private void OpenRibbonWindowWithoutRibbon_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new RibbonWindowWithoutRibbon().Show();
|
|
}
|
|
|
|
private void ZoomSlider_OnValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
|
|
{
|
|
var textFormattingMode = e.NewValue > 1.0 || Math.Abs(e.NewValue - 1.0) < double.Epsilon ? TextFormattingMode.Ideal : TextFormattingMode.Display;
|
|
TextOptions.SetTextFormattingMode(this, textFormattingMode);
|
|
}
|
|
|
|
private void OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
|
|
{
|
|
if (Keyboard.IsKeyDown(Key.LeftCtrl) == false
|
|
&& Keyboard.IsKeyDown(Key.RightCtrl) == false)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var newZoomValue = this.zoomSlider.Value + (e.Delta > 0 ? 0.1 : -0.1);
|
|
|
|
this.zoomSlider.Value = Math.Max(Math.Min(newZoomValue, this.zoomSlider.Maximum), this.zoomSlider.Minimum);
|
|
|
|
e.Handled = true;
|
|
}
|
|
|
|
private void SleepButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
Thread.Sleep(TimeSpan.FromSeconds(10));
|
|
}
|
|
|
|
private void OpenModalRibbonWindow_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new TestWindow().ShowDialog();
|
|
}
|
|
|
|
private void OpenRibbonWindowOnNewThread_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var thread = new Thread(() =>
|
|
{
|
|
var testWindow = new TestWindow();
|
|
testWindow.Closed += OnTestWindowOnClosed;
|
|
testWindow.Show();
|
|
System.Windows.Threading.Dispatcher.Run();
|
|
|
|
void OnTestWindowOnClosed(object o, EventArgs args)
|
|
{
|
|
testWindow.Closed -= OnTestWindowOnClosed;
|
|
((Window)o).Dispatcher?.InvokeShutdown();
|
|
}
|
|
})
|
|
{
|
|
IsBackground = true
|
|
};
|
|
thread.SetApartmentState(ApartmentState.STA);
|
|
|
|
thread.Start();
|
|
}
|
|
|
|
private void OpenRibbonWindowColorized_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new RibbonWindowColorized().Show();
|
|
}
|
|
|
|
private void OpenRibbonWindowWithBackgroundImage_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new RibbonWindowWithBackgroundImage().Show();
|
|
}
|
|
|
|
private void ShowStartScreen_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.startScreen.Shown = false;
|
|
this.startScreen.IsOpen = true;
|
|
}
|
|
|
|
private void HandleAddItemToFontsClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.viewModel.FontsViewModel.FontsData.Add($"Added item {this.viewModel.FontsViewModel.FontsData.Count}");
|
|
}
|
|
|
|
private void CreateThemeResourceDictionaryButton_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.ThemeResourceDictionaryTextBox.Text = ThemeHelper.CreateTheme(ThemeManager.Current.DetectTheme()?.BaseColorScheme ?? "Dark", this.ThemeColorGallery.SelectedColor ?? this.viewModel.ColorViewModel.ThemeColor, changeImmediately: this.ChangeImmediatelyCheckBox.IsChecked ?? false).Item1;
|
|
}
|
|
|
|
private void HandleResetSavedState_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
this.ribbon.AutomaticStateManagement = false;
|
|
this.ribbon.RibbonStateStorage.Reset();
|
|
|
|
System.Windows.Forms.Application.Restart();
|
|
Application.Current.Shutdown();
|
|
}
|
|
|
|
private async void HandleShowMetroMessage(object sender, RoutedEventArgs e)
|
|
{
|
|
#if MahApps_Metro
|
|
var metroWindow = Window.GetWindow(this) as MetroWindow;
|
|
|
|
if (metroWindow is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
await metroWindow.ShowMessageAsync("Test", "Message");
|
|
#else
|
|
ShowMahAppsMetroNotAvailableMessageBox();
|
|
await Task.Yield();
|
|
#endif
|
|
}
|
|
|
|
private void Hyperlink_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
new Window().ShowDialog();
|
|
}
|
|
|
|
private static void ShowMahAppsMetroNotAvailableMessageBox()
|
|
{
|
|
MessageBox.Show("MahApps.Metro is not available in this showcase version.");
|
|
}
|
|
|
|
private void StartSnoop_OnClick(object sender, RoutedEventArgs e)
|
|
{
|
|
var snoopPath = "snoop";
|
|
var alternativeSnoopPath = Environment.GetEnvironmentVariable("snoop_dev_path");
|
|
|
|
if (string.IsNullOrEmpty(alternativeSnoopPath) == false
|
|
&& File.Exists(alternativeSnoopPath))
|
|
{
|
|
snoopPath = alternativeSnoopPath;
|
|
}
|
|
|
|
var startInfo = new ProcessStartInfo(snoopPath, $"inspect --targetPID {Process.GetCurrentProcess().Id}")
|
|
{
|
|
UseShellExecute = true
|
|
};
|
|
try
|
|
{
|
|
using var p = Process.Start(startInfo);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
MessageBox.Show($"Error: {ex.Message}\n\nCommandline: {startInfo.FileName} {startInfo.Arguments}");
|
|
}
|
|
}
|
|
}
|
|
|
|
public class TestRoutedCommand
|
|
{
|
|
public static RoutedCommand TestPresenterCommand { get; } = new RoutedCommand(nameof(TestPresenterCommand), typeof(TestRoutedCommand));
|
|
|
|
public ICommand ItemCommand => TestPresenterCommand;
|
|
|
|
public CommandBinding ItemCommandBinding => new CommandBinding(TestPresenterCommand, OnTestCommandExecuted, CanExecuteTestCommand);
|
|
|
|
private static void CanExecuteTestCommand(object sender, CanExecuteRoutedEventArgs e)
|
|
{
|
|
e.CanExecute = true;
|
|
}
|
|
|
|
private static void OnTestCommandExecuted(object sender, ExecutedRoutedEventArgs e)
|
|
{
|
|
MessageBox.Show("TestPresenterCommand");
|
|
}
|
|
}
|
|
} |