This commit is contained in:
艾竹
2022-12-12 22:33:17 +08:00
parent 02f428d61a
commit 4b798f75a0
60 changed files with 330 additions and 277 deletions

View File

@@ -1,103 +0,0 @@
<UserControl x:Class="AIStudio.Wpf.DiagramHelper.Controls.MultiSelectComboBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<ComboBox Background="Transparent" BorderBrush="Transparent"
x:Name="MultiSelectCombo"
SnapsToDevicePixels="True"
OverridesDefaultStyle="True"
ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.CanContentScroll="True"
IsSynchronizedWithCurrentItem="True">
<ComboBox.Resources>
<Style TargetType="ComboBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ComboBox.Resources>
<ComboBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding Title}"
IsChecked="{Binding Path=IsSelected, Mode=TwoWay}"
Tag="{RelativeSource FindAncestor, AncestorType={x:Type ComboBox}}"
Click="CheckBox_Click" />
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.Template>
<ControlTemplate TargetType="ComboBox">
<Grid >
<ToggleButton x:Name="ToggleButton" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}"
Grid.Column="2" IsChecked="{Binding Path=IsDropDownOpen,Mode=TwoWay,RelativeSource={RelativeSource TemplatedParent}}"
Focusable="false"
ClickMode="Press" HorizontalContentAlignment="Left" >
<ToggleButton.Template>
<ControlTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="12"/>
</Grid.ColumnDefinitions>
<Border
x:Name="Border"
Grid.ColumnSpan="2"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<Border
x:Name="BorderComp"
Grid.Column="0"
CornerRadius="2"
Margin="1"
BorderThickness="0,0,0,0" >
<TextBlock Text="{Binding Path=Text,RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" Padding="3" />
</Border>
<Border x:Name="ArrowBorder" Grid.Column="1" >
<Path
x:Name="Arrow"
Stretch="Fill" Width="5" Height="3"
Fill="Black"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Data="M 0 0 L 4 4 L 8 0 Z"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="ArrowBorder" Property="Background" Value="{DynamicResource Fluent.Ribbon.Brushes.Button.MouseOver.Background}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ToggleButton.Template>
</ToggleButton>
<Popup x:Name="Popup"
Placement="Bottom"
AllowsTransparency="True"
Focusable="False" IsOpen="{TemplateBinding IsDropDownOpen}"
PopupAnimation="Slide">
<Grid x:Name="DropDown"
SnapsToDevicePixels="True"
MinWidth="{TemplateBinding ActualWidth}"
MaxHeight="{TemplateBinding MaxDropDownHeight}">
<Border x:Name="DropDownBorder"
BorderThickness="1" Background="{DynamicResource WhiteBrush}"
BorderBrush="{DynamicResource GrayBrush8}"/>
<ScrollViewer Margin="4,6,4,6" SnapsToDevicePixels="True" DataContext="{Binding}">
<StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Contained" />
</ScrollViewer>
</Grid>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter TargetName="DropDownBorder" Property="MinHeight" Value="95"/>
</Trigger>
<Trigger SourceName="Popup" Property="Popup.AllowsTransparency" Value="true">
<Setter TargetName="DropDownBorder" Property="Margin" Value="0,2,0,0"/>
</Trigger>
<Trigger Property="IsDropDownOpen" Value="true">
<Setter TargetName="ToggleButton" Property="Background" Value="{DynamicResource Fluent.Ribbon.Brushes.Button.MouseOver.Background}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ComboBox.Template>
</ComboBox>
</UserControl>

View File

@@ -1,338 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Collections;
using AIStudio.Wpf.DiagramHelper.Helpers;
using AIStudio.Wpf.DiagramDesigner;
namespace AIStudio.Wpf.DiagramHelper.Controls
{
/// <summary>
/// Interaction logic for MultiSelectComboBox.xaml
/// </summary>
public partial class MultiSelectComboBox : UserControl
{
private ObservableCollection<Node> _nodeList;
public MultiSelectComboBox()
{
InitializeComponent();
_nodeList = new ObservableCollection<Node>();
}
#region Dependency Properties
public static readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(nameof(ItemsSource), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(MultiSelectComboBox.OnItemsSourceChanged)));
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.Register(nameof(SelectedItems), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(MultiSelectComboBox.OnSelectedItemsChanged)));
public static readonly DependencyProperty SelectedValuesProperty =
DependencyProperty.Register(nameof(SelectedValues), typeof(IList), typeof(MultiSelectComboBox), new FrameworkPropertyMetadata(null,
new PropertyChangedCallback(MultiSelectComboBox.OnSelectedValuesChanged)));
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register(nameof(Text), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty));
public static readonly DependencyProperty DefaultTextProperty =
DependencyProperty.Register(nameof(DefaultText), typeof(string), typeof(MultiSelectComboBox), new UIPropertyMetadata(string.Empty));
public string DisplayMemberPath { get; set; }
public string SelectedValuePath { get; set; }
public IList ItemsSource
{
get { return (IList)GetValue(ItemsSourceProperty); }
set
{
SetValue(ItemsSourceProperty, value);
}
}
public IList SelectedItems
{
get { return (IList)GetValue(SelectedItemsProperty); }
set
{
SetValue(SelectedItemsProperty, value);
}
}
public IList SelectedValues
{
get { return (IList)GetValue(SelectedValuesProperty); }
set
{
SetValue(SelectedValuesProperty, value);
}
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
public string DefaultText
{
get { return (string)GetValue(DefaultTextProperty); }
set { SetValue(DefaultTextProperty, value); }
}
#endregion
#region Events
private static void OnItemsSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MultiSelectComboBox control = (MultiSelectComboBox)d;
control.DisplayInControl();
control.SelectNodes();
control.SetText();
}
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MultiSelectComboBox control = (MultiSelectComboBox)d;
control.SelectNodes();
control.SetText();
}
private static void OnSelectedValuesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
MultiSelectComboBox control = (MultiSelectComboBox)d;
control.SelectNodes();
control.SetText();
}
private void CheckBox_Click(object sender, RoutedEventArgs e)
{
CheckBox clickedBox = (CheckBox)sender;
if (clickedBox.Content.ToString() == "All")
{
if (clickedBox.IsChecked.Value)
{
foreach (Node node in _nodeList)
{
node.IsSelected = true;
}
}
else
{
foreach (Node node in _nodeList)
{
node.IsSelected = false;
}
}
}
else
{
int _selectedCount = 0;
foreach (Node s in _nodeList)
{
if (s.IsSelected && s.Object.ToString() != "All")
_selectedCount++;
}
if (_selectedCount == _nodeList.Count - 1)
_nodeList.FirstOrDefault(i => i.Object.ToString() == "All").IsSelected = true;
else
_nodeList.FirstOrDefault(i => i.Object.ToString() == "All").IsSelected = false;
}
SetSelectedItems();
SetText();
}
#endregion
#region Methods
private void SelectNodes()
{
if (SelectedItems != null)
{
foreach (var item in SelectedItems)
{
Node node = _nodeList.FirstOrDefault(i => i.Object == item);
if (node != null)
node.IsSelected = true;
}
}
else if (SelectedValues != null)
{
foreach (var item in SelectedValues)
{
Node node = _nodeList.FirstOrDefault(i => i.Object != null && i.Object.ToString() != "All" && i.Object.GetPropertyValue(SelectedValuePath)?.ToString() == item?.ToString());
if (node != null)
node.IsSelected = true;
}
}
}
private void SetSelectedItems()
{
if (SelectedItems != null)
{
SelectedItems.Clear();
foreach (Node node in _nodeList)
{
if (node.IsSelected && node.Object.ToString() != "All")
{
if (this.ItemsSource.Count > 0)
{
if (SelectedItems != null)
{
SelectedItems.Add(node.Object);
}
}
}
}
}
if (SelectedValues != null)
{
SelectedValues.Clear();
foreach (Node node in _nodeList)
{
if (node.IsSelected && node.Object.ToString() != "All")
{
if (this.ItemsSource.Count > 0)
{
if (SelectedValues != null)
{
SelectedValues.Add(node.Object.GetPropertyValue(SelectedValuePath));
}
}
}
}
}
}
private void DisplayInControl()
{
_nodeList.Clear();
if (this.ItemsSource.Count > 0)
_nodeList.Add(new Node("All", DisplayMemberPath));
foreach (var item in this.ItemsSource)
{
Node node = new Node(item, DisplayMemberPath);
_nodeList.Add(node);
}
MultiSelectCombo.ItemsSource = _nodeList;
}
private void SetText()
{
StringBuilder displayText = new StringBuilder();
foreach (Node s in _nodeList)
{
//不使用ALl来显示
//if (s.IsSelected == true && s.Object.ToString() == "All")
//{
// displayText = new StringBuilder();
// displayText.Append("All");
// break;
//}
//else
if (s.IsSelected == true && s.Object.ToString() != "All")
{
displayText.Append(s.Object);
displayText.Append(',');
}
}
this.Text = displayText.ToString().TrimEnd(new char[] { ',' });
// set DefaultText if nothing else selected
if (string.IsNullOrEmpty(this.Text))
{
this.Text = this.DefaultText;
}
}
#endregion
}
public class Node : INotifyPropertyChanged
{
#region ctor
public Node(object obj, string displayMemberPath)
{
Object = obj;
if (!string.IsNullOrEmpty(displayMemberPath) && Object.ContainsProperty(displayMemberPath))
Title = Object.GetPropertyValue(displayMemberPath).ToString();
else
Title = obj.ToString();
}
#endregion
#region Properties
private object _object;
public object Object
{
get
{
return _object;
}
set
{
_object = value;
NotifyPropertyChanged("Object");
}
}
private string _title;
public string Title
{
get
{
return _title;
}
set
{
_title = value;
NotifyPropertyChanged("Title");
}
}
private bool _isSelected;
public bool IsSelected
{
get
{
return _isSelected;
}
set
{
_isSelected = value;
NotifyPropertyChanged("IsSelected");
}
}
#endregion
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
}

View File

@@ -1,34 +0,0 @@
<Window x:Class="AIStudio.Wpf.DiagramHelper.Controls.PopupWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="{Binding Title}"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterOwner"
x:Name="theView">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<ContentControl Grid.Row="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Content="{Binding ElementName=theView, Path=DataContext}" />
<StackPanel Grid.Row="1"
Orientation="Horizontal"
HorizontalAlignment="Right">
<Button Content="Ok"
IsDefault="True"
Click="Ok_Click"
Margin="5"
Width="100"
Height="30" />
<Button Content="Cancel"
IsCancel="True"
Margin="5"
Width="100"
Height="30" />
</StackPanel>
</Grid>
</Window>

View File

@@ -1,33 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace AIStudio.Wpf.DiagramHelper.Controls
{
/// <summary>
/// PopupWindow.xaml 的交互逻辑
/// </summary>
public partial class PopupWindow : Window
{
public PopupWindow()
{
InitializeComponent();
}
private void Ok_Click(object sender, RoutedEventArgs e)
{
this.DialogResult = true;
this.Close();
}
}
}

View File

@@ -1,63 +0,0 @@
<UserControl x:Class="AIStudio.Wpf.DiagramHelper.Controls.PropertiesView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Border x:Name="border" BorderThickness="1" BorderBrush="{DynamicResource GrayBrush8}">
<Border.Resources>
<ControlTemplate x:Key="validationErrorTemplate">
<DockPanel>
<Image Source="/AIStudio.Wpf.DiagramHelper;component/Images/error.png" Height="16" Width="16"
DockPanel.Dock="Right" Margin="-18,0,0,0"
ToolTip="{Binding ElementName=adorner,
Path=AdornedElement.(Validation.Errors)[0].ErrorContent}">
</Image>
<AdornedElementPlaceholder x:Name="adorner"/>
</DockPanel>
</ControlTemplate>
<Style x:Key="gridLineStyle" TargetType="Line">
<Setter Property="Stroke" Value="{DynamicResource GrayBrush8}" />
<Setter Property="Stretch" Value="Fill" />
<Setter Property="Grid.ZIndex" Value="1000" />
</Style>
<Style x:Key="gridHorizontalLineStyle" TargetType="Line" BasedOn="{StaticResource gridLineStyle}">
<Setter Property="X2" Value="1" />
<Setter Property="VerticalAlignment" Value="Bottom" />
<Setter Property="Grid.ColumnSpan"
Value="{Binding
Path=ColumnDefinitions.Count,
RelativeSource={RelativeSource AncestorType=Grid}}"/>
</Style>
<Style x:Key="gridVerticalLineStyle" TargetType="Line" BasedOn="{StaticResource gridLineStyle}">
<Setter Property="Y2" Value="1" />
<Setter Property="HorizontalAlignment" Value="Right" />
<Setter Property="Grid.RowSpan"
Value="{Binding
Path=RowDefinitions.Count,
RelativeSource={RelativeSource AncestorType=Grid}}"/>
</Style>
</Border.Resources>
<DockPanel x:Name="_panel">
<Border x:Name="_label" Width="50" Height="16">
<TextBlock Text="Empty" TextAlignment="Center" Foreground="Gray"/>
</Border>
<ScrollViewer x:Name="_gridContainer" VerticalScrollBarVisibility="Auto">
<Grid x:Name="_grid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Line Name="_vLine" Grid.Column="0" Grid.RowSpan="1000" Style="{StaticResource gridVerticalLineStyle}"/>
<GridSplitter Name="_splitter" Grid.RowSpan="1000" Margin="0,0,0,0" Width="1"
Background="{DynamicResource GrayBrush8}" Grid.ZIndex="10000"/>
</Grid>
</ScrollViewer>
</DockPanel>
</Border>
</UserControl>

View File

@@ -1,263 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.ComponentModel;
using System.Reflection;
namespace AIStudio.Wpf.DiagramHelper.Controls
{
/// <summary>
/// Interaction logic for PropertiesView.xaml
/// </summary>
public partial class PropertiesView : UserControl
{
#region SelectedObject
public static readonly DependencyProperty SelectedObjectProperty = DependencyProperty.Register("SelectedObject", typeof(object), typeof(PropertiesView), new UIPropertyMetadata(null, OnSelectedObjectChanged));
public object SelectedObject
{
get
{
return (object)GetValue(SelectedObjectProperty);
}
set
{
SetValue(SelectedObjectProperty, value);
}
}
private static void OnSelectedObjectChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
PropertiesView propertyInspector = o as PropertiesView;
if (propertyInspector != null)
propertyInspector.OnSelectedObjectChanged((object)e.OldValue, (object)e.NewValue);
}
protected virtual void OnSelectedObjectChanged(object oldValue, object newValue)
{
// We do not want to process the change now if the grid is initializing (ie. BeginInit/EndInit).
var obj = oldValue as INotifyPropertyChanged;
if (obj != null)
obj.PropertyChanged -= PropertyChanged;
DisplayProperties();
obj = newValue as INotifyPropertyChanged;
if (obj != null)
obj.PropertyChanged += PropertyChanged;
}
#endregion //SelectedObject
public static readonly DependencyProperty NeedBrowsableProperty = DependencyProperty.Register("NeedBrowsable", typeof(bool), typeof(PropertiesView), new UIPropertyMetadata(true));
public bool NeedBrowsable
{
get
{
return (bool)GetValue(NeedBrowsableProperty);
}
set
{
SetValue(NeedBrowsableProperty, value);
}
}
public bool CustomSetting
{
get;
set;
}
public PropertiesView()
{
InitializeComponent();
this.Loaded += PropertiesView_Loaded;
}
private void PropertiesView_Loaded(object sender, RoutedEventArgs e)
{
DisplayProperties();
}
void PropertyChanged(object sender, PropertyChangedEventArgs e)
{
DisplayProperties();
}
private void DisplayProperties()
{
_panel.Children.Clear();
ClearGrid();
if (SelectedObject != null)
{
if (CustomSetting == true)
{
if (SelectedObject.GetType().GetProperty("PropertiesSetting") != null)
{
Dictionary<string, string> settings = SelectedObject.GetType().GetProperty("PropertiesSetting").GetValue(SelectedObject) as Dictionary<string, string>;
int row = 0;
foreach (var setting in settings)
{
var prop = SelectedObject.GetType().GetProperty(setting.Key);
DisplayProperty(prop, row, setting.Value);
row++;
}
}
}
else
{
int row = 0;
foreach (var prop in SelectedObject.GetType().GetProperties())
{
var attr = prop.GetCustomAttributes(typeof(BrowsableAttribute), true);
if (NeedBrowsable == false && (attr.Length == 0 || (attr[0] as BrowsableAttribute).Browsable))
{
DisplayProperty(prop, row);
row++;
}
else if (NeedBrowsable == true && (attr.Length > 0 && (attr[0] as BrowsableAttribute).Browsable))
{
DisplayProperty(prop, row);
row++;
}
}
}
_panel.Children.Add(_gridContainer);
}
else
{
_panel.Children.Add(_label);
}
}
private void ClearGrid()
{
_grid.RowDefinitions.Clear();
for (int i = _grid.Children.Count - 1; i >= 0; i--)
{
if (_grid.Children[i] != _vLine && _grid.Children[i] != _splitter)
_grid.Children.RemoveAt(i);
}
}
private void DisplayProperty(PropertyInfo prop, int row, string name = null)
{
var rowDef = new RowDefinition();
rowDef.Height = new GridLength(Math.Max(20, this.FontSize * 2));
_grid.RowDefinitions.Add(rowDef);
var tb = new TextBlock() { Text = prop.Name };
if (name != null)
{
tb.Text = name;
tb.ToolTip = prop.Name;
}
else
{
var displayAttr = prop.GetCustomAttributes(typeof(DisplayNameAttribute), true);
if (displayAttr.Length > 0)
{
tb.Text = (displayAttr[0] as DisplayNameAttribute).DisplayName;
tb.ToolTip = prop.Name;
}
}
tb.Margin = new Thickness(4);
Grid.SetColumn(tb, 0);
Grid.SetRow(tb, _grid.RowDefinitions.Count - 1);
_grid.Children.Add(tb);
var line = new Line();
line.Style = (Style)border.Resources["gridHorizontalLineStyle"];
Grid.SetRow(line, row);
_grid.Children.Add(line);
Style style = null;
var styleNameAttr = prop.GetCustomAttributes(typeof(StyleNameAttribute), true);
if (styleNameAttr.Length > 0)
{
style = this.FindResource((styleNameAttr[0] as StyleNameAttribute).Name) as Style;
if (style != null)
{
ContentControl content = new ContentControl();
content.Style = style;
content.DataContext = SelectedObject;
Grid.SetColumn(content, 1);
Grid.SetRow(content, _grid.RowDefinitions.Count - 1);
_grid.Children.Add(content);
}
}
if (style == null)
{
var ed = new TextBox();
ed.PreviewKeyDown += new KeyEventHandler(ed_KeyDown);
ed.Margin = new Thickness(0);
ed.VerticalAlignment = VerticalAlignment.Center;
ed.BorderThickness = new Thickness(0);
Grid.SetColumn(ed, 1);
Grid.SetRow(ed, _grid.RowDefinitions.Count - 1);
var binding = new Binding(prop.Name);
binding.Source = SelectedObject;
binding.ValidatesOnExceptions = true;
binding.Mode = BindingMode.OneWay;
if (prop.CanWrite)
{
var mi = prop.GetSetMethod();
if (mi != null && mi.IsPublic)
binding.Mode = BindingMode.TwoWay;
}
ed.SetBinding(TextBox.TextProperty, binding);
var template = (ControlTemplate)border.Resources["validationErrorTemplate"];
Validation.SetErrorTemplate(ed, template);
_grid.Children.Add(ed);
}
}
void ed_KeyDown(object sender, KeyEventArgs e)
{
var ed = sender as TextBox;
if (ed != null)
{
if (e.Key == Key.Enter)
{
ed.GetBindingExpression(TextBox.TextProperty).UpdateSource();
e.Handled = true;
}
else if (e.Key == Key.Escape)
ed.GetBindingExpression(TextBox.TextProperty).UpdateTarget();
}
}
}
[AttributeUsage(AttributeTargets.Property)]
public class StyleNameAttribute : Attribute
{
private string _name;
public StyleNameAttribute(string name)
{
_name = name;
}
public string Name
{
get
{
return _name;
}
}
}
}