mirror of
https://gitee.com/akwkevin/aistudio.-wpf.-diagram
synced 2026-04-22 01:16:36 +08:00
218 lines
7.1 KiB
C#
218 lines
7.1 KiB
C#
// ReSharper disable once CheckNamespace
|
|
|
|
namespace Fluent
|
|
{
|
|
using System;
|
|
using System.Collections;
|
|
using System.Reflection;
|
|
using System.Windows;
|
|
using System.Windows.Input;
|
|
using Fluent.Internal.KnownBoxes;
|
|
|
|
/// <summary>
|
|
/// Helper-Class for switching states in ToggleButton-Groups
|
|
/// </summary>
|
|
public static class ToggleButtonHelper
|
|
{
|
|
private static readonly MethodInfo getVisualRootMethodInfo = typeof(KeyboardNavigation).GetMethod("GetVisualRoot", BindingFlags.NonPublic | BindingFlags.Static);
|
|
|
|
// Grouped buttons
|
|
[ThreadStatic]
|
|
private static Hashtable groupNameToElements;
|
|
|
|
/// <summary>
|
|
/// Handles changes to <see cref="IToggleButton.GroupName" />
|
|
/// </summary>
|
|
public static void OnGroupNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
var toggleButton = (IToggleButton)d;
|
|
var newValue = e.NewValue as string;
|
|
var oldValue = e.OldValue as string;
|
|
|
|
if (newValue == oldValue)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(oldValue) == false)
|
|
{
|
|
Unregister(oldValue, toggleButton);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(newValue))
|
|
{
|
|
return;
|
|
}
|
|
|
|
Register(newValue, toggleButton);
|
|
}
|
|
|
|
private static void Register(string groupName, IToggleButton toggleButton)
|
|
{
|
|
if (groupNameToElements is null)
|
|
{
|
|
groupNameToElements = new Hashtable(1);
|
|
}
|
|
|
|
var elements = (ArrayList)groupNameToElements[groupName];
|
|
if (elements is null)
|
|
{
|
|
elements = new ArrayList(1);
|
|
groupNameToElements[groupName] = elements;
|
|
}
|
|
else
|
|
{
|
|
PurgeDead(elements, null);
|
|
}
|
|
|
|
elements.Add(new WeakReference(toggleButton));
|
|
}
|
|
|
|
private static void Unregister(string groupName, IToggleButton toggleButton)
|
|
{
|
|
if (groupNameToElements is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
var groupNameToElement = (ArrayList)groupNameToElements[groupName];
|
|
if (groupNameToElement != null)
|
|
{
|
|
PurgeDead(groupNameToElement, toggleButton);
|
|
if (groupNameToElement.Count == 0)
|
|
{
|
|
groupNameToElements.Remove(groupName);
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void PurgeDead(ArrayList elements, object elementToRemove)
|
|
{
|
|
var index = 0;
|
|
while (index < elements.Count)
|
|
{
|
|
var target = ((WeakReference)elements[index]).Target;
|
|
if (target is null
|
|
|| target == elementToRemove)
|
|
{
|
|
elements.RemoveAt(index);
|
|
}
|
|
else
|
|
{
|
|
++index;
|
|
}
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the states of all buttons inside the group which <paramref name="toggleButton" /> belongs to.
|
|
/// </summary>
|
|
public static void UpdateButtonGroup(IToggleButton toggleButton)
|
|
{
|
|
var groupName = toggleButton.GroupName;
|
|
|
|
if (string.IsNullOrEmpty(groupName) == false)
|
|
{
|
|
var visualRoot = getVisualRootMethodInfo.Invoke(null, new object[] { (DependencyObject)toggleButton });
|
|
if (groupNameToElements is null)
|
|
{
|
|
groupNameToElements = new Hashtable(1);
|
|
}
|
|
|
|
var groupNameToElement = (ArrayList)groupNameToElements[groupName];
|
|
var index = 0;
|
|
while (index < groupNameToElement.Count)
|
|
{
|
|
var target = ((WeakReference)groupNameToElement[index]).Target as IToggleButton;
|
|
if (target is null)
|
|
{
|
|
groupNameToElement.RemoveAt(index);
|
|
}
|
|
else
|
|
{
|
|
if (target != toggleButton)
|
|
{
|
|
var isCheckedValue = GetIsCheckedValue(target);
|
|
|
|
if (isCheckedValue != 0
|
|
&& visualRoot == getVisualRootMethodInfo.Invoke(null, new object[] { (DependencyObject)target }))
|
|
{
|
|
UncheckToggleButton(target);
|
|
}
|
|
}
|
|
|
|
++index;
|
|
}
|
|
}
|
|
}
|
|
|
|
//else
|
|
//{
|
|
// var parent = toggleButton.Parent;
|
|
// if (parent is null)
|
|
// {
|
|
// return;
|
|
// }
|
|
|
|
// foreach (var child in LogicalTreeHelper.GetChildren(parent))
|
|
// {
|
|
// var childAsToggleButton = child as IToggleButton;
|
|
|
|
// if (childAsToggleButton != null
|
|
// && childAsToggleButton != toggleButton
|
|
// && string.IsNullOrEmpty(childAsToggleButton.GroupName))
|
|
// {
|
|
// var isCheckedValue = GetIsCheckedValue(childAsToggleButton);
|
|
|
|
// if (isCheckedValue != 0)
|
|
// {
|
|
// UncheckToggleButton(childAsToggleButton);
|
|
// }
|
|
// }
|
|
// }
|
|
//}
|
|
}
|
|
|
|
private static void UncheckToggleButton(IToggleButton toggleButton)
|
|
{
|
|
var dependencyObject = toggleButton as DependencyObject;
|
|
|
|
if (dependencyObject is null)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (toggleButton is System.Windows.Controls.MenuItem)
|
|
{
|
|
dependencyObject.SetCurrentValue(System.Windows.Controls.MenuItem.IsCheckedProperty, BooleanBoxes.FalseBox);
|
|
}
|
|
else
|
|
{
|
|
dependencyObject.SetCurrentValue(System.Windows.Controls.Primitives.ToggleButton.IsCheckedProperty, BooleanBoxes.FalseBox);
|
|
}
|
|
}
|
|
|
|
private static int GetIsCheckedValue(IToggleButton childAsToggleButton)
|
|
{
|
|
var isChecked = childAsToggleButton.IsChecked;
|
|
|
|
var isCheckedValue = isChecked.GetValueOrDefault()
|
|
? (isChecked.HasValue
|
|
? 1
|
|
: 0)
|
|
: 0;
|
|
return isCheckedValue;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Handles changes to <see cref="IToggleButton.IsChecked" />
|
|
/// </summary>
|
|
public static void OnIsCheckedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
|
{
|
|
if ((bool)e.NewValue)
|
|
{
|
|
UpdateButtonGroup((IToggleButton)d);
|
|
}
|
|
}
|
|
}
|
|
} |