查找与替换完成

This commit is contained in:
艾竹
2023-04-15 21:55:27 +08:00
parent ce2e44fe49
commit c6bc57140f
15 changed files with 680 additions and 91 deletions

View File

@@ -84,7 +84,10 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
}
set
{
SetProperty(ref _pageViewModel, value);
if (SetProperty(ref _pageViewModel, value))
{
}
}
}

View File

@@ -160,7 +160,7 @@ namespace AIStudio.Wpf.DiagramApp.ViewModels
if (_diagramViewModel != value)
{
if (_diagramViewModel != null)
{
{
_diagramViewModel.PropertyChanged -= DiagramViewModel_PropertyChanged;
}
SetProperty(ref _diagramViewModel, value);

View File

@@ -34,7 +34,7 @@
<dd:ObjectConverter x:Key="ObjectConverter"/>
<dd:MindThemeFillBrushConverter x:Key="MindThemeFillBrushConverter"/>
<dd:MindThemeFontBrushConverter x:Key="MindThemeFontBrushConverter"/>
<converter:NumberConverter x:Key="NumberConverter"/>
<converter:Boolean2VisibilityReConverter x:Key="Boolean2VisibilityReConverter"/>
<converter:NullableToVisibilityConverter x:Key="NullableToVisibilityConverter"/>
@@ -827,7 +827,7 @@
<Fluent:MenuItem Header="直线连接线" Size="Middle" IsCheckable="True" IsChecked="{Binding LineDrawMode,Converter={dd:ConverterValueMapToBool Parameter='ConnectingLineStraight'}, ConverterParameter='ConnectingLineStraight'}" Icon="{iconPacks:Material Kind=VectorLine}"/>
<Fluent:MenuItem Header="折线连接线" Size="Middle" IsCheckable="True" IsChecked="{Binding LineDrawMode,Converter={dd:ConverterValueMapToBool Parameter='ConnectingLineCorner'}, ConverterParameter='ConnectingLineCorner'}" Icon="{iconPacks:Material Kind=VectorPolyline}"/>
<Fluent:MenuItem Header="边界连接线" Size="Middle" IsCheckable="True" IsChecked="{Binding LineDrawMode,Converter={dd:ConverterValueMapToBool Parameter='ConnectingLineBoundary'}, ConverterParameter='ConnectingLineBoundary'}" Icon="{iconPacks:Material Kind=VectorPolylineEdit}"/>
<Fluent:MenuItem Header="自动连接" Size="Middle" IsCheckable="True" IsChecked="{Binding EnableSnapping}" Icon="{iconPacks:Material Kind=TransitConnectionHorizontal}"/>
<Fluent:MenuItem Header="自动连接" Size="Middle" IsCheckable="True" IsChecked="{Binding EnableSnapping}" Icon="{iconPacks:Material Kind=TransitConnectionHorizontal}"/>
<Fluent:SplitButton.Style>
<Style TargetType="{x:Type Fluent:SplitButton}" BasedOn="{StaticResource RibbonSplitButtonStyle}">
<Setter Property="LargeIcon">
@@ -1344,7 +1344,7 @@
Text="快速样式"
Width="190" />
</Fluent:RibbonGroupBox.ToolTip>
</Fluent:RibbonGroupBox>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="插入">
<Fluent:RibbonGroupBox Header="插入"
@@ -1465,7 +1465,7 @@
Width="190" />
</Fluent:SplitButton.ToolTip>
</Fluent:SplitButton>
</Fluent:RibbonGroupBox>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="页面布局">
<Fluent:RibbonGroupBox Header="页面"
@@ -2168,8 +2168,8 @@
Text="主题"
Width="190" />
</Fluent:SplitButton.ToolTip>
</Fluent:SplitButton>
</Fluent:SplitButton>
<Fluent:Button Header="整理布局" Width="50" VerticalAlignment="Top" Command="{Binding PageViewModel.DiagramViewModel.ResetLayoutCommand}">
<Fluent:Button.LargeIcon>
<Path Width="15" Height="15" Stretch="Uniform" Fill="Black" Data="M358.4 0a102.4 102.4 0 0 1 102.4 102.4v819.2a102.4 102.4 0 0 1-102.4 102.4H102.4a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4h256z m0 76.8H102.4a25.6 25.6 0 0 0-25.1904 20.992L76.8 102.4v819.2a25.6 25.6 0 0 0 20.992 25.1904L102.4 947.2h256a25.6 25.6 0 0 0 25.1904-20.992L384 921.6V102.4a25.6 25.6 0 0 0-20.992-25.1904L358.4 76.8z m268.288 547.84a38.4 38.4 0 0 1 50.1248-1.8432l4.1472 3.8912a38.4 38.4 0 0 1 1.8432 50.1248L630.272 742.4h333.7216l4.6592 0.3584c16.7936 2.56 29.696 18.5856 29.696 38.0416 0 21.1968-15.36 38.4-34.3552 38.4h-333.6704l52.4288 65.6384 3.2256 4.6592a38.4 38.4 0 0 1-63.232 43.3152l-102.4-128-3.328-4.9152a38.4 38.4 0 0 1 3.328-43.0592l102.4-128zM921.6 0a102.4 102.4 0 0 1 102.4 102.4v256a102.4 102.4 0 0 1-102.4 102.4h-256a102.4 102.4 0 0 1-102.4-102.4V102.4a102.4 102.4 0 0 1 102.4-102.4h256z m0 76.8h-256a25.6 25.6 0 0 0-25.1904 20.992L640 102.4v256a25.6 25.6 0 0 0 20.992 25.1904L665.6 384h256a25.6 25.6 0 0 0 25.1904-20.992L947.2 358.4V102.4a25.6 25.6 0 0 0-20.992-25.1904L921.6 76.8z"></Path>
@@ -2223,7 +2223,7 @@
Text="全选"
Width="190" />
</Fluent:SplitButton.ToolTip>
</Fluent:SplitButton>
</Fluent:SplitButton>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="视图">
@@ -2253,48 +2253,16 @@
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M819.198 910.218 204.799 910.218c-50.267 0-91.022-40.75-91.022-91.02L113.777 204.822c0-50.29 40.755-91.045 91.022-91.045l614.398 0c50.27 0 91.02 40.755 91.02 91.045l0 614.376C910.218 869.468 869.468 910.218 819.198 910.218zM841.953 227.554c0-25.122-20.385-45.51-45.51-45.51L227.554 182.044c-25.122 0-45.51 20.387-45.51 45.51l0 568.889c0 25.125 20.387 45.535 45.51 45.535l568.889 0c25.125 0 45.51-20.39 45.51-45.535L841.953 227.554zM603.268 400.952l-57.14-57.115 0 335.802 55.505-55.5c13.335-13.31 34.93-13.335 48.265 0 13.33 13.335 13.33 34.95 0 48.29l-105.77 105.765c-1.615 3.415-3.525 6.78-6.37 9.625-7.1 7.08-16.475 10.1-25.76 9.67-9.262 0.46-18.66-2.59-25.76-9.69-2.842-2.85-4.8-6.15-6.347-9.58l-105.79-105.79c-13.335-13.34-13.335-34.955 0-48.29 13.332-13.31 34.927-13.335 48.262 0l55.502 55.5L477.865 343.837l-57.117 57.115c-13.335 13.357-34.952 13.335-48.287 0s-13.335-34.93 0-48.265l115.395-115.37c13.332-13.335 34.927-13.357 48.262 0l115.395 115.37c13.335 13.335 13.335 34.952 0 48.265C638.198 414.286 616.583 414.286 603.268 400.952z"></Path>
</Fluent:Button.LargeIcon>
</Fluent:Button>
</Fluent:RibbonGroupBox>
</Fluent:RibbonGroupBox>
</Fluent:RibbonTabItem>
<Fluent:RibbonTabItem Header="高级">
<Fluent:RibbonGroupBox Header="查找"
IsLauncherVisible="True" >
<Fluent:Button Header="搜索" Width="50" VerticalAlignment="Top" Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}">
<Fluent:Button Header="搜索" Width="50" VerticalAlignment="Top" Command="{Binding PageViewModel.DiagramViewModel.ShowSearchCommand}">
<Fluent:Button.LargeIcon>
<iconPacks:PackIconFontAwesome Kind="SearchSolid" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Fluent:Button.LargeIcon>
</Fluent:Button>
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="3" VerticalAlignment="Top" Margin="0,8,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="24"/>
<RowDefinition Height="24"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtsearch" Text="{Binding PageViewModel.DiagramViewModel.SearchText}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</TextBox.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="1" Padding="6,0" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.SearchUpCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Width="10" Height="10" Stretch="Uniform" Fill="Black" Data="M17,13.41,12.71,9.17a1,1,0,0,0-1.42,0L7.05,13.41a1,1,0,0,0,0,1.42,1,1,0,0,0,1.41,0L12,11.29l3.54,3.54a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29A1,1,0,0,0,17,13.41Z"></Path>
</Button>
<Button Grid.Column="2" Padding="6,0" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Width="10" Height="10" Stretch="Uniform" Fill="Black" Data="M17,9.17a1,1,0,0,0-1.41,0L12,12.71,8.46,9.17a1,1,0,0,0-1.41,0,1,1,0,0,0,0,1.42l4.24,4.24a1,1,0,0,0,1.42,0L17,10.59A1,1,0,0,0,17,9.17Z"></Path>
</Button>
<Line X1="0" Y1="0" X2="150" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom" Grid.ColumnSpan="3"></Line>
<TextBlock Grid.Row="1" Grid.ColumnSpan="3" Margin="2,0,0,0" VerticalAlignment="Center" Text="{Binding PageViewModel.DiagramViewModel.SearchInfo}"/>
</Grid>
</Border>
</Fluent:RibbonGroupBox>
<Fluent:RibbonGroupBox Header="其他">
<Fluent:Button Header="截屏" Width="50" VerticalAlignment="Top" Command="{Binding ScreenshotCommand}">
@@ -2392,7 +2360,7 @@
</dragablz:TabablzControl.HeaderItemTemplate>
<dragablz:TabablzControl.ContentTemplate>
<DataTemplate>
<TabControl ItemsSource="{Binding DiagramViewModels}" SelectedItem="{Binding DiagramViewModel}" Style="{StaticResource TabControlStyle}"
<dd:DiagramTabControl ItemsSource="{Binding DiagramViewModels}" SelectedItem="{Binding DiagramViewModel}" Style="{StaticResource TabControlStyle}"
BorderThickness="0" Margin="0" Padding="0">
<TabControl.ItemContainerStyle>
<Style>
@@ -2469,11 +2437,151 @@
</Grid>
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
</dd:DiagramTabControl>
</DataTemplate>
</dragablz:TabablzControl.ContentTemplate>
</dragablz:TabablzControl>
<Border BorderBrush="Gray" Background="{DynamicResource WindowBackgroundBrush}" BorderThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,24,18,0"
Visibility="{Binding PageViewModel.DiagramViewModel.ShowSearch,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
</Grid.ColumnDefinitions>
<ToggleButton x:Name="replaceToggle" Width="20" Height="20" Padding="5,0" ToolTip="查找与替换切换">
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Path Stretch="Uniform" Fill="Black" Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"></Path>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Content">
<Setter.Value>
<Path Stretch="Uniform" Fill="Black" Data="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"></Path>
</Setter.Value>
</Setter>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<TextBox Grid.Column="1" Width="200" x:Name="txtsearch" Text="{Binding PageViewModel.DiagramViewModel.SearchText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</TextBox.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="查找上一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.SearchUpCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Stretch="Uniform" Fill="Black" Data="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"></Path>
</Button>
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="查找下一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Stretch="Uniform" Fill="Black" Data="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></Path>
</Button>
<Button Grid.Column="4" Width="20" Height="20" Padding="5,0" ToolTip="关闭" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.CloseSearchCommand}">
<Path Stretch="Uniform" Fill="Black" Data="M500 455.8125L727.875 227.8749999999999L772.1250000000001 272.0625L544.1875 500L772.1250000000001 727.875L727.9375 772.125L500 544.1875L272.125 772.125L227.9375000000001 727.875L455.8125 500L227.9375000000001 272.125L272.125 227.8749999999999L500 455.8125z"></Path>
</Button>
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
</Grid>
<Grid Grid.Row="1" Height="24" Visibility="{Binding ElementName=replaceToggle,Path=IsChecked,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" x:Name="txtreplace" Text="{Binding PageViewModel.DiagramViewModel.ReplaceText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
</TextBox>
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.ReplaceCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ObjectConverter}">
<MultiBinding.Bindings>
<Binding ElementName="txtsearch" Path="Text"/>
<Binding ElementName="txtreplace" Path="Text"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
<Path Stretch="Uniform" Fill="Black" Data="M940.3 761.5c-8.5-13.3-19.3-24.8-31.9-34.1 13.3-19.5 20.7-43.7 20.7-69.2 0-61.5-43-111.5-95.9-111.5H671.8c-29.3 0-53.1 23.8-53.1 53.1v304c0 29.3 23.8 53.1 53.1 53.1h160.4c34.3 0 66.6-13.5 90.9-37.9 24.1-24.2 37.3-56 37.1-89.7 0-24.2-6.9-47.6-19.9-67.8z m-67.6 107.7c-10.6 10.6-24.7 16.5-39.5 16.5H689.8V773.6h143.3c14.8 0 28.9 5.9 39.5 16.5 10.6 10.6 16.5 24.7 16.5 39.5s-5.8 29-16.4 39.6z m-25.3-178.9c-2.1 2.5-7.7 8.4-14.3 8.4H689.8v-80.9h143.3c6.6 0 12.2 5.9 14.3 8.4 6.6 8 10.6 20 10.6 32.1 0 12-3.9 24-10.6 32zM456 406.6l-128-320C322.5 73 309.3 64 294.5 64h-64c-14.7 0-28 9-33.4 22.6l-128 320c-7.4 18.5 1.6 39.4 20.1 46.8 18.5 7.4 39.4-1.6 46.8-20.1L178.1 328H347l42.1 105.4c5.6 14.1 19.1 22.6 33.4 22.6 4.5 0 9-0.8 13.4-2.6 18.5-7.4 27.5-28.3 20.1-46.8zM206.9 256l48-120h15.3l48 120H206.9z m345.8 582.3l-113.5 67c-5.7 3.4-12 5-18.3 5-12.3 0-24.3-6.3-31-17.7-10.1-17.1-4.4-39.2 12.7-49.3l38.9-23c-47.1-14.5-88.6-35.2-124.1-62-40.2-30.3-72.5-68.1-96-112.5-39.9-75.3-40.6-143.8-40.6-146.7v-0.1c0-19.9 16.1-36 36-36s35.9 16.1 36 35.9v-0.2c0 0.6 1 56.1 33.6 116 18.7 34.4 44.3 63.8 75.9 87.2 29 21.5 63.4 38.3 102.6 50.1l-23-44.1c-9.2-17.6-2.4-39.4 15.3-48.6 17.6-9.2 39.4-2.4 48.6 15.3l60.5 115.9c8.9 17.1 2.9 38.1-13.6 47.8z"></Path>
</Button>
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="全部替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding PageViewModel.DiagramViewModel.ReplaceAllCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ObjectConverter}">
<MultiBinding.Bindings>
<Binding ElementName="txtsearch" Path="Text"/>
<Binding ElementName="txtreplace" Path="Text"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
<Path Stretch="Uniform" Fill="Black" Data="M618.368 905.813333a88.32 88.32 0 0 1-87.082667-87.082666v-209.408a88.362667 88.362667 0 0 1 87.082667-87.082667h209.408a88.234667 88.234667 0 0 1 87.082667 87.082667v209.408a88.192 88.192 0 0 1-87.082667 87.082666z m-22.912-296.490666v209.408a24.448 24.448 0 0 0 22.912 22.997333h209.408a24.704 24.704 0 0 0 23.168-22.997333v-209.408a24.661333 24.661333 0 0 0-23.168-22.912h-209.408a24.448 24.448 0 0 0-23.04 22.912zM224.853333 826.666667a260.010667 260.010667 0 0 1-69.077333-169.514667h-33.237333l66.090666-110.250667 66.346667 110.250667H219.733333a196.266667 196.266667 0 0 0 51.2 125.354667 213.333333 213.333333 0 0 0 148.992 59.264 32.042667 32.042667 0 1 1 0 64 277.034667 277.034667 0 0 1-195.029333-79.274667z m-28.842666-324.821334a88.405333 88.405333 0 0 1-87.082667-87.082666v-209.066667a88.448 88.448 0 0 1 87.082667-87.338667h209.408a88.405333 88.405333 0 0 1 87.082666 87.338667v209.066667a86.144 86.144 0 0 1-87.082666 87.082666z m-23.168-296.32v209.066667a24.917333 24.917333 0 0 0 23.168 23.168h209.408a22.272 22.272 0 0 0 23.168-23.168v-209.066667a24.704 24.704 0 0 0-23.168-23.168H196.010667a24.704 24.704 0 0 0-23.082667 23.125334z m596.181333 165.077334h35.328a196.693333 196.693333 0 0 0-51.2-128.853334 213.333333 213.333333 0 0 0-149.333333-59.434666 32.085333 32.085333 0 0 1 0-64 277.333333 277.333333 0 0 1 195.157333 79.232 261.205333 261.205333 0 0 1 69.504 173.184h32.853333l-62.421333 110.250666z"></Path>
</Button>
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
</Grid>
<Grid Grid.Row="2" Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="区分大小写" IsChecked="{Binding PageViewModel.DiagramViewModel.SearchCaseMatch}">
<Path Stretch="Uniform" Fill="Black" Data="M20.06,18C20,17.83 19.91,17.54 19.86,17.11C19.19,17.81 18.38,18.16 17.45,18.16C16.62,18.16 15.93,17.92 15.4,17.45C14.87,17 14.6,16.39 14.6,15.66C14.6,14.78 14.93,14.1 15.6,13.61C16.27,13.12 17.21,12.88 18.43,12.88H19.83V12.24C19.83,11.75 19.68,11.36 19.38,11.07C19.08,10.78 18.63,10.64 18.05,10.64C17.53,10.64 17.1,10.76 16.75,11C16.4,11.25 16.23,11.54 16.23,11.89H14.77C14.77,11.46 14.92,11.05 15.22,10.65C15.5,10.25 15.93,9.94 16.44,9.71C16.95,9.5 17.5,9.36 18.13,9.36C19.11,9.36 19.87,9.6 20.42,10.09C20.97,10.58 21.26,11.25 21.28,12.11V16C21.28,16.8 21.38,17.42 21.58,17.88V18H20.06M17.66,16.88C18.11,16.88 18.54,16.77 18.95,16.56C19.35,16.35 19.65,16.07 19.83,15.73V14.16H18.7C16.93,14.16 16.04,14.63 16.04,15.57C16.04,16 16.19,16.3 16.5,16.53C16.8,16.76 17.18,16.88 17.66,16.88M5.46,13.71H9.53L7.5,8.29L5.46,13.71M6.64,6H8.36L13.07,18H11.14L10.17,15.43H4.82L3.86,18H1.93L6.64,6Z"></Path>
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="#cce4f7" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="全字匹配" IsChecked="{Binding PageViewModel.DiagramViewModel.SearchWholeWordMatch}">
<Path Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M62.5 875H937.5V812.5H62.5V875zM875 750H812.5V250H875V750zM704.5 475.8125A147.06250000000003 147.06250000000003 0 0 1 682 524.9375A109.125 109.125 0 0 1 643.9375 558.0625A114.5 114.5 0 0 1 589.8125000000001 570.125C577.4375 570.125 566.0625 568.625 555.625 565.5624999999999A109.99999999999999 109.99999999999999 0 0 1 527.3125000000001 552.7499999999999A107.75 107.75 0 0 1 504.5000000000001 532.875L493.3125000000001 516.75V713.875H437.5V250H493.3125V285.9375L501.1875 274.9999999999999C506.625 268.6249999999999 513 263.1249999999999 520.1875 258.1874999999999C527.5000000000001 253.3124999999999 535.7500000000001 249.4374999999999 545.0625 246.5624999999999C554.375 243.6875 564.6875 242.3124999999999 576.1875 242.3124999999999C598.25 242.3124999999999 617.8125 246.7499999999999 634.7499999999999 255.5624999999999C651.7499999999999 264.5 665.9375 276.6874999999999 677.375 292.1874999999999C688.8124999999999 307.8124999999999 697.4374999999999 326.1249999999999 703.2499999999999 347.1249999999999C709.0624999999999 368.2499999999999 712 391.0624999999999 712 415.6874999999999A234.74999999999997 234.74999999999997 0 0 1 704.5 475.8124999999999zM612.0625 513.75C621.4999999999999 509.3125 629.6875 502.75 636.4375 494.1250000000001C643.25 485.375 648.5625 474.5625 652.375 461.8125000000001C655.5625 450.9375000000001 657.5000000000001 438.625 657.9375000000001 425.1250000000001L657.5000000000001 417.3125000000001C657.5000000000001 396.8750000000001 655.4375000000001 378.5625000000001 651.2500000000001 363.0000000000001A117.87500000000001 117.87500000000001 0 0 0 633.8750000000001 324.625C626.5625 314.5 617.6250000000001 306.8125 607.5625000000001 301.7500000000001C587.4375000000001 291.625 560.0625000000001 291.375 540.7500000000001 300.8125A79 79 0 0 0 516.1875 319.3125A79.5625 79.5625 0 0 0 502.5625 342.25S491.375 370.1874999999999 491.375 401.4374999999999C491.375 432.6874999999999 502.5625 464.0624999999999 502.5625 464.0624999999999C506.4375 475.1249999999999 511.0625 483.9374999999999 516.5625 490.9374999999999C523.6875000000001 499.8749999999999 532.5625 507.1249999999999 543.0625 512.4999999999999C553.5625 517.875 565.875 520.5625 579.75 520.5625C591.625 520.5625 602.5 518.25 612.0625 513.75zM937.5 187.5H62.5V125H937.5V187.5zM175.8125 375L130.3125 248.0625H62.5L64.0625 252.5624999999999L216.625 695.4375H275.4375L430.75 248.0624999999999H363.125L314.5 375H175.8125zM245.875 598.625H244.5000000000001L187.9375 426.5625H303.0000000000001L245.8750000000001 598.625z">
<Path.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Path.RenderTransform>
</Path>
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="#cce4f7" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<TextBlock Grid.Column="1" Margin="2,0,0,0" VerticalAlignment="Center" Text="{Binding PageViewModel.DiagramViewModel.SearchInfo}"/>
</StackPanel>
</Grid>
</Grid>
</Border>
<DockPanel Grid.Row="1" >
<Fluent:ComboBox Size="Small" IsEditable="False" dd:EnumHelper.Enum="{x:Type model:ColorType}" SelectedItem="{Binding ColorType}" BorderThickness="0" BorderBrush="Transparent" Background="Transparent" Template="{StaticResource ComboboxControlTemplate1}" >
<Fluent:ComboBox.ItemTemplate>

View File

@@ -199,6 +199,15 @@ namespace AIStudio.Wpf.DiagramDesigner
_service.PropertyChanged += _service_PropertyChanged;
this.Loaded += DesignerCanvas_Loaded;
this.IsVisibleChanged += DesignerCanvas_IsVisibleChanged;
}
private void DesignerCanvas_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (IsVisible)
{
this.Focus();
}
}
private void DesignerCanvas_Loaded(object sender, RoutedEventArgs e)
@@ -354,8 +363,8 @@ namespace AIStudio.Wpf.DiagramDesigner
protected override void OnMouseMove(MouseEventArgs e)
{
//var focusedElement = Keyboard.FocusedElement;
//Debug.WriteLine("focusedElement" + focusedElement?.ToString());
var focusedElement = Keyboard.FocusedElement;
Debug.WriteLine("focusedElement" + focusedElement?.ToString());
base.OnMouseMove(e);

View File

@@ -0,0 +1,46 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace AIStudio.Wpf.DiagramDesigner.Controls
{
public class DiagramTabControl : TabControl
{
public DiagramTabControl()
{
// Attach event handler to TabControl.SelectionChanged event
this.SelectionChanged += DiagramTabControl_SelectionChanged;
this.IsVisibleChanged += DiagramTabControl_IsVisibleChanged;
}
private void DiagramTabControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
foreach (var item in this.Items)
{
if (item is DiagramViewModel viewModel)
{
viewModel.ShowSearch = false;
}
}
}
private void DiagramTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
// Iterate through all TabItems and manually set the Visibility property
foreach (var item in this.Items)
{
if (item is DiagramViewModel viewModel)
{
if (item != this.SelectedItem)
{
viewModel.ShowSearch = false;
}
}
}
}
}
}

View File

@@ -315,7 +315,7 @@
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid x:Name="selectedGrid" IsHitTestVisible="{Binding IsHitTestVisible}" >
<Grid x:Name="selectedGrid" IsHitTestVisible="{Binding IsHitTestVisible}" >
<Grid.ContextMenu>
<ContextMenu ItemsSource="{Binding MenuOptions}" Visibility="{Binding ShowMenuOptions,Converter={StaticResource BooleanToVisibilityConverter}}">
<ContextMenu.ItemContainerStyle>
@@ -819,7 +819,7 @@
</ResourceDictionary>
</UserControl.Resources>
<Border>
<Grid>
<Control x:Name="control">
<Control.Style>
<Style TargetType="Control">
@@ -842,7 +842,7 @@
AllowDrop="{Binding AllowDrop}">
<dd:DesignerCanvas.LayoutTransform>
<ScaleTransform ScaleX="{Binding ZoomValue}" ScaleY="{Binding ZoomValue}" />
</dd:DesignerCanvas.LayoutTransform>
</dd:DesignerCanvas.LayoutTransform>
</dd:DesignerCanvas>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
@@ -903,5 +903,5 @@
</Style>
</Control.Style>
</Control>
</Border>
</Grid>
</UserControl>

View File

@@ -27,6 +27,13 @@ namespace AIStudio.Wpf.DiagramDesigner
{
this.Resources.MergedDictionaries.Add(ResourceDictionary);
}
this.IsVisibleChanged += DiagramControl_IsVisibleChanged;
}
private void DiagramControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
}
public static readonly DependencyProperty ResourceDictionaryProperty = DependencyProperty.Register(nameof(ResourceDictionary), typeof(ResourceDictionary), typeof(DiagramControl), new UIPropertyMetadata(null, OnResourceDictionaryChanged));

View File

@@ -12,6 +12,8 @@
<dd:ArrowPathConverter x:Key="ArrowPathConverter"/>
<dd:ArrowSizeConverter x:Key="ArrowSizeConverter"/>
<dd:MathConverter x:Key="MathAddConverter" Operation="Add" />
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<Style x:Key="LineStyle" TargetType="Path">
<Setter Property="Stroke" Value="{Binding ColorViewModel.LineColor,Converter={StaticResource ColorBrushConverter}}"/>
<Style.Triggers>
@@ -88,6 +90,20 @@
</Path>
</Grid>
<Rectangle Canvas.Left="{Binding StartPoint.X}"
Canvas.Top="{Binding StartPoint.Y}"
Fill="DarkRed"
Width="{Binding SourceConnectorInfo.ConnectorWidth}"
Height="{Binding SourceConnectorInfo.ConnectorHeight}"
Visibility="{Binding IsSelected,Converter={StaticResource BooleanToVisibilityConverter}}" />
<Ellipse Canvas.Left="{Binding EndPoint.X}"
Canvas.Top="{Binding EndPoint.Y}"
Fill="DarkRed"
Width="{Binding SinkConnectorInfo.ConnectorWidth}"
Height="{Binding SinkConnectorInfo.ConnectorHeight}"
Visibility="{Binding IsSelected,Converter={StaticResource BooleanToVisibilityConverter}}" />
<Ellipse x:Name="ball" Fill="{Binding ColorViewModel.FillColor,Converter={StaticResource ColorBrushConverter}}"
Width="{Binding ColorViewModel.LineWidth,Converter={StaticResource MathAddConverter},ConverterParameter=4}"
Height="{Binding ColorViewModel.LineWidth,Converter={StaticResource MathAddConverter},ConverterParameter=4}"

View File

@@ -612,6 +612,8 @@ namespace AIStudio.Wpf.DiagramDesigner
StartAngle = PathGeneratorResult.SourceMarkerAngle;
EndAngle = PathGeneratorResult.TargetMarkerAngle;
StartPoint = new PointBase(source.Value.X - Area.Left - SourceConnectorInfo.ConnectorWidth / 2, source.Value.Y - Area.Top - SourceConnectorInfo.ConnectorHeight / 2) ;
EndPoint = new PointBase(target.Value.X - Area.Left - SinkConnectorInfo.ConnectorWidth / 2 , target.Value.Y - Area.Top - SinkConnectorInfo.ConnectorHeight / 2 );
var paths = Labels.Count > 0 ? PathGeneratorResult.Paths.Select(p => new SvgPath(p)).ToArray() : Array.Empty<SvgPath>();
foreach (var label in Labels)

View File

@@ -104,5 +104,34 @@ namespace AIStudio.Wpf.DiagramDesigner
get; set;
} = e => e.KeyboardDevice.Modifiers == ModifierKeys.Shift | e.Key == Key.G;
[Description("Search shortcut (CTRL+F by default)")]
public Func<KeyEventArgs, bool> Search
{
get; set;
} = e => e.KeyboardDevice.Modifiers == ModifierKeys.Control | e.Key == Key.F;
[Description("Search Down shortcut (F3 by default)")]
public Func<KeyEventArgs, bool> SearchDown
{
get; set;
} = e => e.Key == Key.F3;
[Description("Search Up shortcut (Shift+F3 by default)")]
public Func<KeyEventArgs, bool> SearchUp
{
get; set;
} = e => e.KeyboardDevice.Modifiers == ModifierKeys.Shift | e.Key == Key.F3;
[Description("Replace shortcut (Alt+R by default)")]
public Func<KeyEventArgs, bool> Replace
{
get; set;
} = e => e.KeyboardDevice.Modifiers == ModifierKeys.Alt | e.Key == Key.R;
[Description("Replace All shortcut (Alt+A by default)")]
public Func<KeyEventArgs, bool> ReplaceAll
{
get; set;
} = e => e.KeyboardDevice.Modifiers == ModifierKeys.Alt | e.Key == Key.A;
}
}

View File

@@ -4,6 +4,7 @@ using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Reactive.Linq;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
@@ -576,6 +577,19 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private bool _showSearch;
public bool ShowSearch
{
get
{
return _showSearch;
}
set
{
SetProperty(ref _showSearch, value);
}
}
private string _searchText;
public string SearchText
{
@@ -589,6 +603,19 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private string _replaceText;
public string ReplaceText
{
get
{
return _replaceText;
}
set
{
SetProperty(ref _replaceText, value);
}
}
private string _searchInfo;
public string SearchInfo
{
@@ -602,6 +629,32 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private bool _searchCaseMatch;
public bool SearchCaseMatch
{
get
{
return _searchCaseMatch;
}
set
{
SetProperty(ref _searchCaseMatch, value);
}
}
private bool _searchWholeWordMatch;
public bool SearchWholeWordMatch
{
get
{
return _searchWholeWordMatch;
}
set
{
SetProperty(ref _searchWholeWordMatch, value);
}
}
protected ObservableCollection<CinchMenuItem> menuOptions;
public IEnumerable<CinchMenuItem> MenuOptions
{
@@ -1028,6 +1081,24 @@ namespace AIStudio.Wpf.DiagramDesigner
}
}
private ICommand _showSearchCommand;
public ICommand ShowSearchCommand
{
get
{
return this._showSearchCommand ?? (this._showSearchCommand = new SimpleCommand(ExecuteEnable, this.ExecutedShowSearchCommand));
}
}
private ICommand _closeSearchCommand;
public ICommand CloseSearchCommand
{
get
{
return this._closeSearchCommand ?? (this._closeSearchCommand = new SimpleCommand(ExecuteEnable, this.ExecutedCloseSearchCommand));
}
}
private ICommand _searchDownCommand;
public ICommand SearchDownCommand
{
@@ -1045,6 +1116,24 @@ namespace AIStudio.Wpf.DiagramDesigner
return this._searchUpCommand ?? (this._searchUpCommand = new SimpleCommand(ExecuteEnable, this.ExecutedSearchUpCommand));
}
}
private ICommand _replaceCommand;
public ICommand ReplaceCommand
{
get
{
return this._replaceCommand ?? (this._replaceCommand = new SimpleCommand(ExecuteEnable, this.ExecutedSearchReplaceCommand));
}
}
private ICommand _replaceAllCommand;
public ICommand ReplaceAllCommand
{
get
{
return this._replaceAllCommand ?? (this._replaceAllCommand = new SimpleCommand(ExecuteEnable, this.ExecutedSearchReplaceAllCommand));
}
}
#endregion
#region ctor和初始化
@@ -1499,6 +1588,7 @@ namespace AIStudio.Wpf.DiagramDesigner
Dictionary<SelectableDesignerItemViewModelBase, bool> infos = selectedItems.ToDictionary(p => p, p => p.IsSelected);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
ClearSelectedItems();
foreach (var item in selectedItems)
{
item.IsSelected = true;
@@ -3002,6 +3092,31 @@ namespace AIStudio.Wpf.DiagramDesigner
UngroupCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.Search(e))
{
ShowSearchCommand.Execute(null);
return true;
}
else if (DiagramOption.ShortcutOption.SearchDown(e))
{
SearchDownCommand.Execute(SearchText);
return true;
}
else if (DiagramOption.ShortcutOption.SearchUp(e))
{
SearchUpCommand.Execute(SearchText);
return true;
}
else if (DiagramOption.ShortcutOption.Replace(e))
{
ReplaceCommand.Execute(new object[] { SearchText, ReplaceText });
return true;
}
else if (DiagramOption.ShortcutOption.ReplaceAll(e))
{
ReplaceAllCommand.Execute(new object[] { SearchText, ReplaceText });
return true;
}
return false;
}
@@ -3034,12 +3149,23 @@ namespace AIStudio.Wpf.DiagramDesigner
}
private void ExecutedShowSearchCommand(object parameter)
{
ShowSearch = true;
}
private void ExecutedCloseSearchCommand(object parameter)
{
ShowSearch = false;
}
private void ExecutedSearchUpCommand(object obj)
{
if (obj != null)
{
var selecteddesign = SelectedItem as DesignerItemViewModelBase;
var searchitems = Items.OfType<DesignerItemViewModelBase>().Where(p => p.Text?.Contains(obj.ToString()) == true).ToList();
var selecteddesign = SelectedItem as SelectableDesignerItemViewModelBase;
var searchitems = Items.OfType<SelectableDesignerItemViewModelBase>().Where(p => SearchMatch(p.Text, obj.ToString()) == true).ToList();
if (searchitems.Count > 0)
{
int selectindex = 0;
@@ -3079,8 +3205,8 @@ namespace AIStudio.Wpf.DiagramDesigner
{
if (!string.IsNullOrEmpty(obj?.ToString()))
{
var selecteddesign = SelectedItem as DesignerItemViewModelBase;
var searchitems = Items.OfType<DesignerItemViewModelBase>().Where(p => p.Text?.Contains(obj.ToString()) == true).ToList();
var selecteddesign = SelectedItem as SelectableDesignerItemViewModelBase;
var searchitems = Items.OfType<SelectableDesignerItemViewModelBase>().Where(p => SearchMatch(p.Text, obj.ToString()) == true).ToList();
if (searchitems.Count > 0)
{
int selectindex = 0;
@@ -3115,6 +3241,85 @@ namespace AIStudio.Wpf.DiagramDesigner
SearchInfo = null;
}
}
private bool SearchMatch(string input, string searchtext)
{
if (input == null || searchtext == null)
return false;
if (SearchCaseMatch == true && SearchWholeWordMatch == true)
{
return input == searchtext;
}
else if (SearchCaseMatch == true && SearchWholeWordMatch == false)
{
return input.Contains(searchtext);
}
else if (SearchCaseMatch == false && SearchWholeWordMatch == true)
{
return input.ToLower() == searchtext.ToLower();
}
else
{
return input.ToLower().Contains(searchtext.ToLower());
}
}
private string ReplaceSearch(string input, string searchtext, string replcetext)
{
if (SearchCaseMatch == true)
{
return input.Replace(searchtext, replcetext);
}
else
{
return Regex.Replace(input, searchtext, replcetext, RegexOptions.IgnoreCase);
}
}
private void ExecutedSearchReplaceCommand(object obj)
{
if (obj is object[] array && array.Length == 2)
{
var items = SelectedItems.Where(p => SearchMatch(p.Text, array[0]?.ToString()) == true).ToList();
Dictionary<SelectableDesignerItemViewModelBase, string> infos = items.ToDictionary(p => p, p => p.Text);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
item.Text = ReplaceSearch(item.Text, array[0]?.ToString(), array[1]?.ToString());
}
},
() => {
foreach (var item in infos)
{
item.Key.Text = item.Value;
}
});
}
}
private void ExecutedSearchReplaceAllCommand(object obj)
{
if (obj is object[] array && array.Length == 2)
{
var items = Items.Where(p => SearchMatch(p.Text, array[0]?.ToString()) == true).ToList();
Dictionary<SelectableDesignerItemViewModelBase, string> infos = items.ToDictionary(p => p, p => p.Text);
DoCommandManager.DoNewCommand(this.ToString(),
() => {
foreach (var item in items)
{
item.Text = ReplaceSearch(item.Text, array[0]?.ToString(), array[1]?.ToString());
}
},
() => {
foreach (var item in infos)
{
item.Key.Text = item.Value;
}
});
}
}
#endregion
}
}

View File

@@ -204,6 +204,14 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get;
}
ICommand ShowSearchCommand
{
get;
}
ICommand CloseSearchCommand
{
get;
}
ICommand SearchDownCommand
{
get;
@@ -212,6 +220,14 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get;
}
ICommand ReplaceCommand
{
get;
}
ICommand ReplaceAllCommand
{
get;
}
event DiagramEventHandler Event;
@@ -303,6 +319,30 @@ namespace AIStudio.Wpf.DiagramDesigner
{
get; set;
}
bool ShowSearch
{
get; set;
}
string SearchText
{
get; set;
}
string ReplaceText
{
get; set;
}
string SearchInfo
{
get; set;
}
bool SearchCaseMatch
{
get; set;
}
bool SearchWholeWordMatch
{
get; set;
}
#region
IDrawModeViewModel DrawModeViewModel
{

View File

@@ -1,12 +1,16 @@
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
xmlns:controls="clr-namespace:AIStudio.Wpf.Mind.Controls"
xmlns:dd="https://gitee.com/akwkevin/aistudio.-wpf.-diagram">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Themes/MindNode.xaml"/>
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.Mind;component/Styles/Button.xaml" />
<ResourceDictionary Source="pack://application:,,,/AIStudio.Wpf.DiagramDesigner;component/Styles/ComboBox.xaml" />
</ResourceDictionary.MergedDictionaries>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<dd:ObjectConverter x:Key="ObjectConverter"/>
<Style x:Key="AIStudio.Styles.MindEditor" TargetType="{x:Type controls:MindEditor}">
<Setter Property="Template">
<Setter.Value>
@@ -22,6 +26,146 @@
<!-- Diagram Control -->
<dd:DiagramControl Grid.Row="1" x:Name="PART_DiagramControl" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Border x:Name="PART_SearchControl" Grid.Row="1" BorderBrush="Gray" Background="White" BorderThickness="1" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,1,1,0"
Visibility="{Binding ShowSearch,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid Grid.IsSharedSizeScope="True">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
</Grid.ColumnDefinitions>
<ToggleButton x:Name="replaceToggle" Width="20" Height="20" Padding="5,0" ToolTip="查找与替换切换">
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Content">
<Setter.Value>
<Path Stretch="Uniform" Fill="Black" Data="M7.41,8.58L12,13.17L16.59,8.58L18,10L12,16L6,10L7.41,8.58Z"></Path>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Content">
<Setter.Value>
<Path Stretch="Uniform" Fill="Black" Data="M7.41,15.41L12,10.83L16.59,15.41L18,14L12,8L6,14L7.41,15.41Z"></Path>
</Setter.Value>
</Setter>
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<TextBox Grid.Column="1" Width="200" x:Name="txtsearch" Text="{Binding SearchText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</TextBox.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="查找上一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchUpCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Stretch="Uniform" Fill="Black" Data="M20,11V13H8L13.5,18.5L12.08,19.92L4.16,12L12.08,4.08L13.5,5.5L8,11H20Z"></Path>
</Button>
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="查找下一个" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Stretch="Uniform" Fill="Black" Data="M4,11V13H16L10.5,18.5L11.92,19.92L19.84,12L11.92,4.08L10.5,5.5L16,11H4Z"></Path>
</Button>
<Button Grid.Column="4" Width="20" Height="20" Padding="5,0" ToolTip="关闭" Style="{StaticResource FlatButtonStyle}" Command="{Binding CloseSearchCommand}">
<Path Stretch="Uniform" Fill="Black" Data="M500 455.8125L727.875 227.8749999999999L772.1250000000001 272.0625L544.1875 500L772.1250000000001 727.875L727.9375 772.125L500 544.1875L272.125 772.125L227.9375000000001 727.875L455.8125 500L227.9375000000001 272.125L272.125 227.8749999999999L500 455.8125z"></Path>
</Button>
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
</Grid>
<Grid Grid.Row="1" Height="24" Visibility="{Binding ElementName=replaceToggle,Path=IsChecked,Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*" SharedSizeGroup="Column2"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column3"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column4"/>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column5"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" x:Name="txtreplace" Text="{Binding ReplaceText,Mode=OneWayToSource}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
</TextBox>
<Line Grid.Column="1" X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="2" Width="20" Height="20" Padding="5,0" ToolTip="替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding ReplaceCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ObjectConverter}">
<MultiBinding.Bindings>
<Binding ElementName="txtsearch" Path="Text"/>
<Binding ElementName="txtreplace" Path="Text"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
<Path Stretch="Uniform" Fill="Black" Data="M940.3 761.5c-8.5-13.3-19.3-24.8-31.9-34.1 13.3-19.5 20.7-43.7 20.7-69.2 0-61.5-43-111.5-95.9-111.5H671.8c-29.3 0-53.1 23.8-53.1 53.1v304c0 29.3 23.8 53.1 53.1 53.1h160.4c34.3 0 66.6-13.5 90.9-37.9 24.1-24.2 37.3-56 37.1-89.7 0-24.2-6.9-47.6-19.9-67.8z m-67.6 107.7c-10.6 10.6-24.7 16.5-39.5 16.5H689.8V773.6h143.3c14.8 0 28.9 5.9 39.5 16.5 10.6 10.6 16.5 24.7 16.5 39.5s-5.8 29-16.4 39.6z m-25.3-178.9c-2.1 2.5-7.7 8.4-14.3 8.4H689.8v-80.9h143.3c6.6 0 12.2 5.9 14.3 8.4 6.6 8 10.6 20 10.6 32.1 0 12-3.9 24-10.6 32zM456 406.6l-128-320C322.5 73 309.3 64 294.5 64h-64c-14.7 0-28 9-33.4 22.6l-128 320c-7.4 18.5 1.6 39.4 20.1 46.8 18.5 7.4 39.4-1.6 46.8-20.1L178.1 328H347l42.1 105.4c5.6 14.1 19.1 22.6 33.4 22.6 4.5 0 9-0.8 13.4-2.6 18.5-7.4 27.5-28.3 20.1-46.8zM206.9 256l48-120h15.3l48 120H206.9z m345.8 582.3l-113.5 67c-5.7 3.4-12 5-18.3 5-12.3 0-24.3-6.3-31-17.7-10.1-17.1-4.4-39.2 12.7-49.3l38.9-23c-47.1-14.5-88.6-35.2-124.1-62-40.2-30.3-72.5-68.1-96-112.5-39.9-75.3-40.6-143.8-40.6-146.7v-0.1c0-19.9 16.1-36 36-36s35.9 16.1 36 35.9v-0.2c0 0.6 1 56.1 33.6 116 18.7 34.4 44.3 63.8 75.9 87.2 29 21.5 63.4 38.3 102.6 50.1l-23-44.1c-9.2-17.6-2.4-39.4 15.3-48.6 17.6-9.2 39.4-2.4 48.6 15.3l60.5 115.9c8.9 17.1 2.9 38.1-13.6 47.8z"></Path>
</Button>
<Button Grid.Column="3" Width="20" Height="20" Padding="5,0" ToolTip="全部替换" Style="{StaticResource FlatButtonStyle}" Command="{Binding ReplaceAllCommand}">
<Button.CommandParameter>
<MultiBinding Converter="{StaticResource ObjectConverter}">
<MultiBinding.Bindings>
<Binding ElementName="txtsearch" Path="Text"/>
<Binding ElementName="txtreplace" Path="Text"/>
</MultiBinding.Bindings>
</MultiBinding>
</Button.CommandParameter>
<Path Stretch="Uniform" Fill="Black" Data="M618.368 905.813333a88.32 88.32 0 0 1-87.082667-87.082666v-209.408a88.362667 88.362667 0 0 1 87.082667-87.082667h209.408a88.234667 88.234667 0 0 1 87.082667 87.082667v209.408a88.192 88.192 0 0 1-87.082667 87.082666z m-22.912-296.490666v209.408a24.448 24.448 0 0 0 22.912 22.997333h209.408a24.704 24.704 0 0 0 23.168-22.997333v-209.408a24.661333 24.661333 0 0 0-23.168-22.912h-209.408a24.448 24.448 0 0 0-23.04 22.912zM224.853333 826.666667a260.010667 260.010667 0 0 1-69.077333-169.514667h-33.237333l66.090666-110.250667 66.346667 110.250667H219.733333a196.266667 196.266667 0 0 0 51.2 125.354667 213.333333 213.333333 0 0 0 148.992 59.264 32.042667 32.042667 0 1 1 0 64 277.034667 277.034667 0 0 1-195.029333-79.274667z m-28.842666-324.821334a88.405333 88.405333 0 0 1-87.082667-87.082666v-209.066667a88.448 88.448 0 0 1 87.082667-87.338667h209.408a88.405333 88.405333 0 0 1 87.082666 87.338667v209.066667a86.144 86.144 0 0 1-87.082666 87.082666z m-23.168-296.32v209.066667a24.917333 24.917333 0 0 0 23.168 23.168h209.408a22.272 22.272 0 0 0 23.168-23.168v-209.066667a24.704 24.704 0 0 0-23.168-23.168H196.010667a24.704 24.704 0 0 0-23.082667 23.125334z m596.181333 165.077334h35.328a196.693333 196.693333 0 0 0-51.2-128.853334 213.333333 213.333333 0 0 0-149.333333-59.434666 32.085333 32.085333 0 0 1 0-64 277.333333 277.333333 0 0 1 195.157333 79.232 261.205333 261.205333 0 0 1 69.504 173.184h32.853333l-62.421333 110.250666z"></Path>
</Button>
<Line Grid.ColumnSpan="5" X1="0" Y1="0" X2="300" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom"></Line>
</Grid>
<Grid Grid.Row="2" Height="24">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" SharedSizeGroup="Column1"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Orientation="Horizontal">
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="区分大小写" IsChecked="{Binding SearchCaseMatch}">
<Path Stretch="Uniform" Fill="Black" Data="M20.06,18C20,17.83 19.91,17.54 19.86,17.11C19.19,17.81 18.38,18.16 17.45,18.16C16.62,18.16 15.93,17.92 15.4,17.45C14.87,17 14.6,16.39 14.6,15.66C14.6,14.78 14.93,14.1 15.6,13.61C16.27,13.12 17.21,12.88 18.43,12.88H19.83V12.24C19.83,11.75 19.68,11.36 19.38,11.07C19.08,10.78 18.63,10.64 18.05,10.64C17.53,10.64 17.1,10.76 16.75,11C16.4,11.25 16.23,11.54 16.23,11.89H14.77C14.77,11.46 14.92,11.05 15.22,10.65C15.5,10.25 15.93,9.94 16.44,9.71C16.95,9.5 17.5,9.36 18.13,9.36C19.11,9.36 19.87,9.6 20.42,10.09C20.97,10.58 21.26,11.25 21.28,12.11V16C21.28,16.8 21.38,17.42 21.58,17.88V18H20.06M17.66,16.88C18.11,16.88 18.54,16.77 18.95,16.56C19.35,16.35 19.65,16.07 19.83,15.73V14.16H18.7C16.93,14.16 16.04,14.63 16.04,15.57C16.04,16 16.19,16.3 16.5,16.53C16.8,16.76 17.18,16.88 17.66,16.88M5.46,13.71H9.53L7.5,8.29L5.46,13.71M6.64,6H8.36L13.07,18H11.14L10.17,15.43H4.82L3.86,18H1.93L6.64,6Z"></Path>
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="#cce4f7" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<ToggleButton Width="20" Height="20" Padding="2,0" ToolTip="全字匹配" IsChecked="{Binding SearchWholeWordMatch}">
<Path Stretch="Uniform" Fill="Black" RenderTransformOrigin="0.5,0.5" Data="M62.5 875H937.5V812.5H62.5V875zM875 750H812.5V250H875V750zM704.5 475.8125A147.06250000000003 147.06250000000003 0 0 1 682 524.9375A109.125 109.125 0 0 1 643.9375 558.0625A114.5 114.5 0 0 1 589.8125000000001 570.125C577.4375 570.125 566.0625 568.625 555.625 565.5624999999999A109.99999999999999 109.99999999999999 0 0 1 527.3125000000001 552.7499999999999A107.75 107.75 0 0 1 504.5000000000001 532.875L493.3125000000001 516.75V713.875H437.5V250H493.3125V285.9375L501.1875 274.9999999999999C506.625 268.6249999999999 513 263.1249999999999 520.1875 258.1874999999999C527.5000000000001 253.3124999999999 535.7500000000001 249.4374999999999 545.0625 246.5624999999999C554.375 243.6875 564.6875 242.3124999999999 576.1875 242.3124999999999C598.25 242.3124999999999 617.8125 246.7499999999999 634.7499999999999 255.5624999999999C651.7499999999999 264.5 665.9375 276.6874999999999 677.375 292.1874999999999C688.8124999999999 307.8124999999999 697.4374999999999 326.1249999999999 703.2499999999999 347.1249999999999C709.0624999999999 368.2499999999999 712 391.0624999999999 712 415.6874999999999A234.74999999999997 234.74999999999997 0 0 1 704.5 475.8124999999999zM612.0625 513.75C621.4999999999999 509.3125 629.6875 502.75 636.4375 494.1250000000001C643.25 485.375 648.5625 474.5625 652.375 461.8125000000001C655.5625 450.9375000000001 657.5000000000001 438.625 657.9375000000001 425.1250000000001L657.5000000000001 417.3125000000001C657.5000000000001 396.8750000000001 655.4375000000001 378.5625000000001 651.2500000000001 363.0000000000001A117.87500000000001 117.87500000000001 0 0 0 633.8750000000001 324.625C626.5625 314.5 617.6250000000001 306.8125 607.5625000000001 301.7500000000001C587.4375000000001 291.625 560.0625000000001 291.375 540.7500000000001 300.8125A79 79 0 0 0 516.1875 319.3125A79.5625 79.5625 0 0 0 502.5625 342.25S491.375 370.1874999999999 491.375 401.4374999999999C491.375 432.6874999999999 502.5625 464.0624999999999 502.5625 464.0624999999999C506.4375 475.1249999999999 511.0625 483.9374999999999 516.5625 490.9374999999999C523.6875000000001 499.8749999999999 532.5625 507.1249999999999 543.0625 512.4999999999999C553.5625 517.875 565.875 520.5625 579.75 520.5625C591.625 520.5625 602.5 518.25 612.0625 513.75zM937.5 187.5H62.5V125H937.5V187.5zM175.8125 375L130.3125 248.0625H62.5L64.0625 252.5624999999999L216.625 695.4375H275.4375L430.75 248.0624999999999H363.125L314.5 375H175.8125zM245.875 598.625H244.5000000000001L187.9375 426.5625H303.0000000000001L245.8750000000001 598.625z">
<Path.RenderTransform>
<ScaleTransform ScaleY="-1"/>
</Path.RenderTransform>
</Path>
<ToggleButton.Style>
<Style BasedOn="{StaticResource FlatButtonStyle}" TargetType="{x:Type ToggleButton}">
<Setter Property="Background" Value="Transparent"/>
<Style.Triggers>
<Trigger Property="IsChecked" Value="True">
<Trigger.Setters>
<Setter Property="Background" Value="#cce4f7" />
</Trigger.Setters>
</Trigger>
</Style.Triggers>
</Style>
</ToggleButton.Style>
</ToggleButton>
<TextBlock Grid.Column="1" Margin="2,0,0,0" VerticalAlignment="Center" Text="{Binding SearchInfo}"/>
</StackPanel>
</Grid>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>

View File

@@ -20,12 +20,15 @@ namespace AIStudio.Wpf.Mind.Controls
/// </summary>
[TemplatePart(Name = PART_DiagramControl, Type = typeof(DiagramControl))]
[TemplatePart(Name = PART_ContentControl, Type = typeof(ContentControl))]
[TemplatePart(Name = PART_SearchControl, Type = typeof(Border))]
public partial class MindEditor : UserControl
{
public const string PART_DiagramControl = "PART_DiagramControl";
public const string PART_ContentControl = "PART_ContentControl";
public const string PART_SearchControl = "PART_SearchControl";
private DiagramControl _diagramControl;
private ContentControl _contentControl;
private Border _searchborder;
private MindDiagramViewModel _diagramViewModel;
@@ -56,7 +59,16 @@ namespace AIStudio.Wpf.Mind.Controls
_diagramControl.DataContext = _diagramViewModel;
_contentControl = GetTemplateChild(PART_ContentControl) as ContentControl;
_contentControl.DataContext = _diagramViewModel;
if (_contentControl != null)
{
_contentControl.DataContext = _diagramViewModel;
}
_searchborder = GetTemplateChild(PART_SearchControl) as Border;
if (_searchborder != null)
{
_searchborder.DataContext = _diagramViewModel;
}
GetDataFunc = GetData;
}

View File

@@ -627,39 +627,7 @@
<Path Width="18" Height="18" Stretch="Uniform" Fill="Black" Data="M911.958045 890.721335l-241.415018-246.54112a336.369964 336.369964 0 1 0-58.095828 45.158522l247.029321 252.643623a36.859118 36.859118 0 0 0 51.749225 0 37.103218 37.103218 0 0 0 0.7323-51.261025zM176.240286 404.473897a261.431228 261.431228 0 1 1 261.431228 261.431228A261.675328 261.675328 0 0 1 176.240286 404.473897z"></Path>
<TextBlock>搜索</TextBlock>
</StackPanel>
</Button>
<Border BorderBrush="Gray" BorderThickness="1" CornerRadius="3">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="txtsearch" Text="{Binding SearchText}" VerticalContentAlignment="Center" BorderThickness="0" Background="Transparent">
<TextBox.InputBindings>
<KeyBinding Key="Enter" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</TextBox.InputBindings>
<i:Interaction.Triggers>
<i:EventTrigger EventName="LostFocus">
<i:InvokeCommandAction Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</TextBox>
<Line X1="0" Y1="0" X2="0" Y2="100" Stroke="Gray" StrokeThickness="0.5" HorizontalAlignment="Right"></Line>
<Button Grid.Column="1" Padding="6,0" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchUpCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Width="10" Height="10" Stretch="Uniform" Fill="Black" Data="M17,13.41,12.71,9.17a1,1,0,0,0-1.42,0L7.05,13.41a1,1,0,0,0,0,1.42,1,1,0,0,0,1.41,0L12,11.29l3.54,3.54a1,1,0,0,0,.7.29,1,1,0,0,0,.71-.29A1,1,0,0,0,17,13.41Z"></Path>
</Button>
<Button Grid.Column="2" Padding="6,0" Style="{StaticResource FlatButtonStyle}" Command="{Binding SearchDownCommand}" CommandParameter="{Binding ElementName=txtsearch,Path=Text}">
<Path Width="10" Height="10" Stretch="Uniform" Fill="Black" Data="M17,9.17a1,1,0,0,0-1.41,0L12,12.71,8.46,9.17a1,1,0,0,0-1.41,0,1,1,0,0,0,0,1.42l4.24,4.24a1,1,0,0,0,1.42,0L17,10.59A1,1,0,0,0,17,9.17Z"></Path>
</Button>
<Line X1="0" Y1="0" X2="150" Y2="0" Stroke="Gray" StrokeThickness="0.5" VerticalAlignment="Bottom" Grid.ColumnSpan="3"></Line>
<TextBlock Grid.Row="1" Grid.ColumnSpan="3" Margin="2,0,0,0" VerticalAlignment="Center" Text="{Binding SearchInfo}" />
</Grid>
</Border>
</Button>
</StackPanel>
</TabItem>
</TabControl>