Merge pull request #16 from HandyOrg/master

fix
This commit is contained in:
眾尋 authored and GitHub committed 2019-05-20 14:17:32 +08:00
commit 3757ed7167
61 files changed
+2589 -400

No files matched your search

+6 -2
View File
@@ -54,6 +54,10 @@ Step 3:enjoy coding
## Latest examples
### Grid
![Grid](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Grid.gif)
### SideMenu
![SideMenu](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/SideMenu.png)
@@ -70,12 +74,12 @@ Step 3:enjoy coding
![WaveProgressBar](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/WaveProgressBar.gif)
## History publication
### Badge
![Badge](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Badge.png)
## History publication
### Gravatar
![Gravatar](https://raw.githubusercontent.com/NaBian/HandyControl/master/Resources/Gravatar.gif)
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 MiB

@@ -315,6 +315,9 @@
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\WindowsForm_16x.png">
<Link>Resources\Img\LeftMainContent\WindowsForm_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\WindowsForm_16x.png">
<Link>Resources\Img\LeftMainContent\GridPane_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\qq-group.jpg">
<Link>Resources\Img\qq-group.jpg</Link>
</Resource>
@@ -38,4 +38,9 @@
<ItemGroup>
<None Remove="Themes\Styles\Base\TreeViewBaseStyle.xaml" />
</ItemGroup>
<ItemGroup>
<Resource Include="..\..\Shared\HandyControl_Shared\Resources\dropper.cur">
<Link>Resources\dropper.cur</Link>
</Resource>
</ItemGroup>
</Project>
@@ -887,6 +887,147 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableTopAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="2" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup_AutoComplete" StaysOpen="False" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Row="1"/>
<ToggleButton Grid.Row="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="0" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Row="1" Grid.Column="0" x:Name="border" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Grid.Column="1" Grid.Row="1" Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--标题在左侧的Handy式可编辑下拉框模板-->
<ControlTemplate x:Key="ComboBoxPlusEditableLeftTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
@@ -1009,6 +1150,144 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableLeftAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="1" x:Name="PART_Popup_AutoComplete" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="1" Grid.ColumnSpan="2" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}"/>
<ToggleButton Grid.Column="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Column="1" x:Name="border" Background="Transparent" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="2" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Handy式下拉框样式-->
<Style x:Key="ComboBoxPlusBaseStyle" BasedOn="{StaticResource ComboBoxExtendBaseStyle}" TargetType="controls:ComboBox">
<Setter Property="Template" Value="{StaticResource ComboBoxPlusTopTemplate}"/>
@@ -1027,6 +1306,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Top"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopAutoCompleteTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
@@ -1034,6 +1321,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Left"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftAutoCompleteTemplate}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
@@ -395,6 +395,9 @@
<Generator>TextTemplatingFileGenerator</Generator>
<LastGenOutput>MessageToken.cs</LastGenOutput>
</Content>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\GridPane_16x.png">
<Link>Resources\Img\LeftMainContent\GridPane_16x.png</Link>
</Resource>
<Resource Include="..\..\Shared\HandyControlDemo_Shared\Resources\Img\LeftMainContent\MainMenuControl_16x.png">
<Link>Resources\Img\LeftMainContent\MainMenuControl_16x.png</Link>
</Resource>
@@ -100,6 +100,11 @@
<LastGenOutput>Lang.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\..\Shared\HandyControl_Shared\Resources\dropper.cur">
<Link>Resources\dropper.cur</Link>
</Resource>
</ItemGroup>
<Import Project="..\..\Shared\HandyControl_Shared\HandyControl_Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -824,6 +824,140 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableTopAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="2" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup_AutoComplete" StaysOpen="False" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Row="1"/>
<ToggleButton Grid.Row="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="0" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Row="1" Grid.Column="0" x:Name="border" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Grid.Column="1" Grid.Row="1" Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--标题在左侧的Handy式可编辑下拉框模板-->
<ControlTemplate x:Key="ComboBoxPlusEditableLeftTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
@@ -939,6 +1073,137 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableLeftAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="1" x:Name="PART_Popup_AutoComplete" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="1" Grid.ColumnSpan="2" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}"/>
<ToggleButton Grid.Column="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Column="1" x:Name="border" Background="Transparent" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="2" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Handy式下拉框样式-->
<Style x:Key="ComboBoxPlusBaseStyle" BasedOn="{StaticResource ComboBoxExtendBaseStyle}" TargetType="controls:ComboBox">
<Setter Property="Template" Value="{StaticResource ComboBoxPlusTopTemplate}"/>
@@ -957,6 +1222,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Top"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopAutoCompleteTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
@@ -964,6 +1237,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Left"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftAutoCompleteTemplate}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
@@ -141,6 +141,11 @@
<LastGenOutput>Lang.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Resource Include="..\..\Shared\HandyControl_Shared\Resources\dropper.cur">
<Link>Resources\dropper.cur</Link>
</Resource>
</ItemGroup>
<Import Project="..\..\Shared\HandyControl_Shared\HandyControl_Shared.projitems" Label="Shared" />
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
@@ -887,6 +887,147 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableTopAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.ColumnSpan="2" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal" Margin="{TemplateBinding Padding}">
<TextBlock Margin="1,0,0,0" Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="0" Grid.Row="1" x:Name="PART_Popup_AutoComplete" StaysOpen="False" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="0" Grid.ColumnSpan="2" FontSize="12" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}" Grid.Row="1"/>
<ToggleButton Grid.Row="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" Grid.Column="0" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Row="1" Grid.Column="0" x:Name="border" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Grid.Column="1" Grid.Row="1" Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--标题在左侧的Handy式可编辑下拉框模板-->
<ControlTemplate x:Key="ComboBoxPlusEditableLeftTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
@@ -1009,6 +1150,144 @@
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="ComboBoxPlusEditableLeftAutoCompleteTemplate" TargetType="controls:ComboBox">
<ControlTemplate.Resources>
<Storyboard x:Key="StoryboardShow">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,-18" Duration="0:0:.2"/>
</Storyboard>
<Storyboard x:Key="StoryboardHidden">
<ThicknessAnimation Storyboard.TargetName="TextBlockError" Storyboard.TargetProperty="Margin" To="9,0,0,4" Duration="0:0:0"/>
</Storyboard>
</ControlTemplate.Resources>
<Grid x:Name="templateRoot" SnapsToDevicePixels="true" Height="{Binding Path=(controls:InfoElement.ContentHeight),RelativeSource={RelativeSource TemplatedParent}}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding Path=(controls:InfoElement.TitleWidth),RelativeSource={RelativeSource TemplatedParent}}"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto" MinWidth="30"/>
</Grid.ColumnDefinitions>
<StackPanel VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Margin="0,8,6,8" Visibility="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource String2VisibilityConverter}}" Orientation="Horizontal">
<TextBlock Text="{Binding Path=(controls:InfoElement.Title),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter TextElement.Foreground="{DynamicResource DangerBrush}" Margin="4,0,0,0" Content="{Binding Path=(controls:InfoElement.Symbol),RelativeSource={RelativeSource TemplatedParent}}" Visibility="{Binding Path=(controls:InfoElement.Necessary),RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}"/>
</StackPanel>
<Popup Grid.Column="1" x:Name="PART_Popup" AllowsTransparency="true" Grid.ColumnSpan="2" IsOpen="{Binding IsDropDownOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect" Fill="{Binding Background, ElementName=dropDownBorder}" Height="{Binding ActualHeight, ElementName=dropDownBorder}" Width="{Binding ActualWidth, ElementName=dropDownBorder}"/>
</Canvas>
<ItemsPresenter KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<Popup Grid.Column="1" x:Name="PART_Popup_AutoComplete" AllowsTransparency="true" Grid.ColumnSpan="2" PopupAnimation="{StaticResource {x:Static SystemParameters.ComboBoxPopupAnimationKey}}" Placement="Bottom">
<Border CornerRadius="{Binding Path=(controls:BorderElement.CornerRadius),RelativeSource={RelativeSource TemplatedParent}}" x:Name="dropDownBorder_AutoComplete" MaxHeight="{TemplateBinding MaxDropDownHeight}" MinWidth="{Binding ActualWidth, ElementName=templateRoot}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1" Background="{DynamicResource RegionBrush}">
<ScrollViewer Margin="0,4" x:Name="DropDownScrollViewer_AutoComplete">
<controls:SimplePanel RenderOptions.ClearTypeHint="Enabled">
<Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
<Rectangle x:Name="opaqueRect_AutoComplete" Fill="{Binding Background, ElementName=dropDownBorder_AutoComplete}" Height="{Binding ActualHeight, ElementName=dropDownBorder_AutoComplete}" Width="{Binding ActualWidth, ElementName=dropDownBorder_AutoComplete}"/>
</Canvas>
<StackPanel Name="PART_AutoCompletePanel" KeyboardNavigation.DirectionalNavigation="Contained" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</controls:SimplePanel>
</ScrollViewer>
</Border>
</Popup>
<TextBlock Grid.Column="1" Grid.ColumnSpan="2" Text="{TemplateBinding ErrorStr}" Name="TextBlockError" VerticalAlignment="Bottom" Margin="9,0,0,4" Foreground="{DynamicResource DangerBrush}"/>
<ToggleButton Grid.Column="1" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Padding="{TemplateBinding Padding}" Content="{Binding Path=(controls:InfoElement.Placeholder),RelativeSource={RelativeSource TemplatedParent}}" x:Name="toggleButton" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.ColumnSpan="2" IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxWatermarkToggleButton}"/>
<Border Grid.Column="1" x:Name="border" Background="Transparent" Margin="-1,1">
<TextBox x:Name="PART_EditableTextBox" Padding="{TemplateBinding Padding}" Background="{TemplateBinding Background}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" IsReadOnly="{Binding IsReadOnly, RelativeSource={RelativeSource TemplatedParent}}" Style="{StaticResource ComboBoxEditableTextBox}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<Button Command="interactivity:ControlCommands.Clear" Margin="0,0,26,0" Visibility="Collapsed" Name="ButtonClear" Width="16" Grid.Column="2" Style="{StaticResource ButtonIcon}" Padding="0,6" controls:IconElement.Geometry="{StaticResource DeleteFillCircleGeometry}" Foreground="{TemplateBinding BorderBrush}"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="HasItems" Value="false">
<Setter Property="Height" TargetName="dropDownBorder" Value="95"/>
<Setter Property="Height" TargetName="dropDownBorder_AutoComplete" Value="95"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true"/>
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
</MultiTrigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="DropDownScrollViewer_AutoComplete" Value="false">
<Setter Property="Canvas.Top" TargetName="opaqueRect_AutoComplete" Value="{Binding VerticalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
<Setter Property="Canvas.Left" TargetName="opaqueRect_AutoComplete" Value="{Binding HorizontalOffset, ElementName=DropDownScrollViewer_AutoComplete}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="IsFocused" Value="false" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource SecondaryBorderBrush}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="IsFocused" Value="true" SourceName="PART_EditableTextBox"/>
</MultiTrigger.Conditions>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</MultiTrigger>
<Trigger Property="IsFocused" Value="True" SourceName="PART_EditableTextBox">
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBrush}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="toggleButton"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="border"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true" SourceName="ButtonClear"/>
<Condition Property="ShowClearButton" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Visible" TargetName="ButtonClear"/>
</MultiTrigger>
<Trigger Property="IsError" Value="true">
<Setter Property="BorderBrush" Value="{DynamicResource DangerBrush}"/>
<Trigger.EnterActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardShow}"/>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard Storyboard="{StaticResource StoryboardHidden}"/>
</Trigger.ExitActions>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value="0.4" TargetName="toggleButton"/>
<Setter Property="Opacity" Value="0.4" TargetName="border"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<!--Handy式下拉框样式-->
<Style x:Key="ComboBoxPlusBaseStyle" BasedOn="{StaticResource ComboBoxExtendBaseStyle}" TargetType="controls:ComboBox">
<Setter Property="Template" Value="{StaticResource ComboBoxPlusTopTemplate}"/>
@@ -1027,6 +1306,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Top"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableTopAutoCompleteTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
@@ -1034,6 +1321,14 @@
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftTemplate}"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsEditable" Value="True"/>
<Condition Property="controls:InfoElement.TitleAlignment" Value="Left"/>
<Condition Property="AutoComplete" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource ComboBoxPlusEditableLeftAutoCompleteTemplate}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
@@ -292,6 +292,7 @@
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Controls\SearchBarDemoViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Controls\SideMenuDemoViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Controls\StepBarDemoViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Controls\TabControlDemoViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Controls\WindowDemoViewModel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\DemoViewModelBase!1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)ViewModel\Main\ContributorsViewModel.cs" />
@@ -114,6 +114,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 基础布局 的本地化字符串。
/// </summary>
public static string BasicLayout {
get {
return ResourceManager.GetString("BasicLayout", resourceCulture);
}
}
/// <summary>
/// 查找类似 闪烁 的本地化字符串。
/// </summary>
@@ -135,9 +144,9 @@ namespace HandyControlDemo.Properties.Langs {
/// <summary>
/// 查找类似 边框 的本地化字符串。
/// </summary>
public static string Border1 {
public static string Border {
get {
return ResourceManager.GetString("Border1", resourceCulture);
return ResourceManager.GetString("Border", resourceCulture);
}
}
@@ -276,6 +285,24 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 分栏偏移 的本地化字符串。
/// </summary>
public static string ColumnOffset {
get {
return ResourceManager.GetString("ColumnOffset", resourceCulture);
}
}
/// <summary>
/// 查找类似 分栏间隔 的本地化字符串。
/// </summary>
public static string ColumnSpacing {
get {
return ResourceManager.GetString("ColumnSpacing", resourceCulture);
}
}
/// <summary>
/// 查找类似 组合框 的本地化字符串。
/// </summary>
@@ -627,6 +654,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 混合布局 的本地化字符串。
/// </summary>
public static string HybridLayout {
get {
return ResourceManager.GetString("HybridLayout", resourceCulture);
}
}
/// <summary>
/// 查找类似 忽略 的本地化字符串。
/// </summary>
@@ -1086,6 +1122,15 @@ namespace HandyControlDemo.Properties.Langs {
}
}
/// <summary>
/// 查找类似 响应式布局 的本地化字符串。
/// </summary>
public static string ResponsiveLayout {
get {
return ResourceManager.GetString("ResponsiveLayout", resourceCulture);
}
}
/// <summary>
/// 查找类似 富文本框 的本地化字符串。
/// </summary>
@@ -309,9 +309,6 @@
<data name="TreeView" xml:space="preserve">
<value>TreeView</value>
</data>
<data name="Border1" xml:space="preserve">
<value>Border</value>
</data>
<data name="ScrollViewer" xml:space="preserve">
<value>ScrollViewer</value>
</data>
@@ -585,4 +582,22 @@
<data name="Grid" xml:space="preserve">
<value>Grid</value>
</data>
<data name="BasicLayout" xml:space="preserve">
<value>Basic layout</value>
</data>
<data name="ColumnSpacing" xml:space="preserve">
<value>Column spacing</value>
</data>
<data name="HybridLayout" xml:space="preserve">
<value>Hybrid layout</value>
</data>
<data name="ColumnOffset" xml:space="preserve">
<value>Column offset</value>
</data>
<data name="ResponsiveLayout" xml:space="preserve">
<value>Responsive layout</value>
</data>
<data name="Border" xml:space="preserve">
<value>Border</value>
</data>
</root>
@@ -309,7 +309,7 @@
<data name="TreeView" xml:space="preserve">
<value>树视图</value>
</data>
<data name="Border1" xml:space="preserve">
<data name="Border" xml:space="preserve">
<value>边框</value>
</data>
<data name="ScrollViewer" xml:space="preserve">
@@ -585,4 +585,19 @@
<data name="Grid" xml:space="preserve">
<value>栅格</value>
</data>
<data name="BasicLayout" xml:space="preserve">
<value>基础布局</value>
</data>
<data name="ColumnSpacing" xml:space="preserve">
<value>分栏间隔</value>
</data>
<data name="HybridLayout" xml:space="preserve">
<value>混合布局</value>
</data>
<data name="ColumnOffset" xml:space="preserve">
<value>分栏偏移</value>
</data>
<data name="ResponsiveLayout" xml:space="preserve">
<value>响应式布局</value>
</data>
</root>
@@ -72,7 +72,7 @@ namespace HandyControlDemo.Service
var list = new List<string>();
for (var i = 1; i <= 9; i++)
{
list.Add(converter.Convert(Properties.Langs.Lang.Text, null, i, CultureInfo.CurrentCulture)?.ToString());
list.Add($"{converter.Convert(Properties.Langs.Lang.Text, null, i, CultureInfo.CurrentCulture)}{i}");
}
return list;
@@ -4,6 +4,9 @@
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
Background="{DynamicResource RegionBrush}">
<controls:TransitioningContentControl>
<controls:Clock Margin="32"/>
<StackPanel Orientation="Horizontal" Margin="32">
<controls:Clock/>
<controls:ListClock Margin="16,0,0,0"/>
</StackPanel>
</controls:TransitioningContentControl>
</UserControl>
@@ -15,12 +15,12 @@
<controls:ComboBox ItemsSource="{Binding DataList}" SelectedIndex="0" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr1}" Margin="0,32,0,0" Text="{x:Static langs:Lang.ContentDemoStr}"/>
<controls:ComboBox ShowClearButton="True" ItemsSource="{Binding DataList}" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr2}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
<controls:ComboBox ItemsSource="{Binding DataList}" IsEditable="True" SelectedIndex="0" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr1}" Margin="0,32,0,0" Text="{x:Static langs:Lang.ContentDemoStr}"/>
<controls:ComboBox ShowClearButton="True" ItemsSource="{Binding DataList}" IsEditable="True" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr2}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
<controls:ComboBox AutoComplete="True" ShowClearButton="True" ItemsSource="{Binding DataList}" IsEditable="True" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr2}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
<controls:ComboBox ItemsSource="{Binding DataList}" Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" Margin="0,32,0,0" Text="{x:Static langs:Lang.ContentDemoStr}"/>
<controls:ComboBox ShowClearButton="True" ItemsSource="{Binding DataList}" Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
<controls:ComboBox ItemsSource="{Binding DataList}" IsEditable="True" Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" Margin="0,32,0,0" Text="{x:Static langs:Lang.ContentDemoStr}"/>
<controls:ComboBox ShowClearButton="True" ItemsSource="{Binding DataList}" IsEditable="True" Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
<controls:ComboBox AutoComplete="True" ShowClearButton="True" ItemsSource="{Binding DataList}" IsEditable="True" Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" controls:InfoElement.Necessary="True" Margin="0,32,0,0"/>
</StackPanel>
</ScrollViewer>
</controls:TransitioningContentControl>
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
namespace HandyControlDemo.UserControl
{
@@ -9,7 +8,7 @@ namespace HandyControlDemo.UserControl
{
InitializeComponent();
CoverFlowMain.AddRange(new List<Uri>
CoverFlowMain.AddRange(new []
{
new Uri(@"pack://application:,,,/Resources/Img/Album/1.jpg"),
new Uri(@"pack://application:,,,/Resources/Img/Album/2.jpg"),
@@ -3,57 +3,153 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
xmlns:extension="clr-namespace:HandyControl.Tools.Extension;assembly=HandyControl"
xmlns:langs="clr-namespace:HandyControlDemo.Properties.Langs"
Background="{DynamicResource RegionBrush}">
<ScrollViewer>
<StackPanel Margin="32">
<controls:Row>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<TextBlock Text="{x:Static langs:Lang.BasicLayout}" Style="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left"/>
<controls:Row Margin="0,20,0,0">
<controls:Col Span="24">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
</controls:Row>
<controls:Row Margin="0,20,0,0">
<controls:Col Span="12">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="12">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
</controls:Row>
<controls:Row Margin="0,20,0,0">
<controls:Col Span="8">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="8">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="8">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
</controls:Row>
<controls:Row Margin="0,20,0,0">
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="6">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="6">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
</controls:Row>
<controls:Row Margin="0,20,0,0">
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="4">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="4">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col>
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4" Margin="10"/>
<controls:Col Span="4">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<TextBlock Text="{x:Static langs:Lang.ColumnSpacing}" Margin="0,32,0,0" Style="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left"/>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<TextBlock Text="{x:Static langs:Lang.HybridLayout}" Margin="0,32,0,0" Style="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left"/>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="16">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="8">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="8">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="8">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="16">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="4">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<TextBlock Text="{x:Static langs:Lang.ColumnOffset}" Margin="0,32,0,0" Style="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left"/>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="6" Offset="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="6" Offset="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Span="6" Offset="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<controls:Row Margin="0,20,0,0" Gutter="20">
<controls:Col Span="12" Offset="6">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
<TextBlock Text="{x:Static langs:Lang.ResponsiveLayout}" Margin="0,32,0,0" Style="{StaticResource TextBlockLargeBold}" HorizontalAlignment="Left"/>
<controls:Row Margin="0,20,0,0" Gutter="10">
<controls:Col Layout="{extension:ColLayout Xs=8, Sm=6, Md=4, Lg=3, Xl=1}">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Layout="{extension:ColLayout Xs=4, Sm=6, Md=8, Lg=9, Xl=11}">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Layout="{extension:ColLayout Xs=4, Sm=6, Md=8, Lg=9, Xl=11}">
<Border Background="{DynamicResource BorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
<controls:Col Layout="{extension:ColLayout Xs=8, Sm=6, Md=4, Lg=3, Xl=1}">
<Border Background="{DynamicResource SecondaryBorderBrush}" Height="36" CornerRadius="4"/>
</controls:Col>
</controls:Row>
</StackPanel>
@@ -2,12 +2,22 @@
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Background="{DynamicResource RegionBrush}"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl">
DataContext="{Binding TabControlDemo,Source={StaticResource Locator}}"
xmlns:controls="clr-namespace:HandyControl.Controls;assembly=HandyControl"
xmlns:interactivity="clr-namespace:HandyControl.Interactivity;assembly=HandyControl">
<controls:TransitioningContentControl>
<controls:ScrollViewer HorizontalScrollBarVisibility="Auto">
<interactivity:Interaction.Triggers>
<interactivity:RoutedEventTrigger RoutedEvent="controls:TabItem.Closing">
<interactivity:EventToCommand Command="{Binding ClosingCmd}" PassEventArgsToCommand="True" />
</interactivity:RoutedEventTrigger>
<interactivity:RoutedEventTrigger RoutedEvent="controls:TabItem.Closed">
<interactivity:EventToCommand Command="{Binding ClosedCmd}" PassEventArgsToCommand="True" />
</interactivity:RoutedEventTrigger>
</interactivity:Interaction.Triggers>
<StackPanel>
<Label Style="{StaticResource LabelPrimary}" Content="Default" Margin="32,32,0,0" HorizontalAlignment="Left"/>
<controls:TabControl Margin="32,16,32,0" Width="800" Height="300">
<controls:TabControl ShowOverflowButton="False" ShowScrollButton="True" Margin="32,16,32,0" Width="800" Height="300" IsScrollable="True">
<controls:TabItem Header="TabItem1">
<controls:SimplePanel Background="White"/>
</controls:TabItem>
@@ -17,7 +17,11 @@
<controls:TimePicker Width="380" controls:InfoElement.TitleWidth="140" controls:InfoElement.TitleAlignment="Left" controls:InfoElement.Placeholder="{x:Static langs:Lang.PlsEnterContent}" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr3}" Style="{StaticResource TimePickerExtend}" controls:InfoElement.Necessary="True" Margin="0,16,0,0"/>
</StackPanel>
<StackPanel Margin="32,0,0,0">
<controls:TimePicker ShowClearButton="True" Style="{StaticResource TimePickerPlus}"/>
<controls:TimePicker ShowClearButton="True" Style="{StaticResource TimePickerPlus}">
<controls:TimePicker.Clock>
<controls:ListClock/>
</controls:TimePicker.Clock>
</controls:TimePicker>
<controls:TimePicker Margin="0,16,0,0" IsEnabled="False" Style="{StaticResource TimePickerPlus}"/>
<controls:TimePicker ShowClearButton="True" Style="{StaticResource TimePickerPlus}" controls:InfoElement.Title="{x:Static langs:Lang.TitleDemoStr1}" Margin="0,32,0,0"/>
@@ -161,7 +161,7 @@
<Image Source="../../Resources/Img/LeftMainContent/ToolBar_16x.png"/>
</controls:EdgeElement.LeftContent>
</ListBoxItem>
<ListBoxItem Tag="{x:Static data:MessageToken.BorderDemoCtl}" Content="{x:Static langs:Lang.Border1}">
<ListBoxItem Tag="{x:Static data:MessageToken.BorderDemoCtl}" Name="ListBoxItemBorder">
<controls:EdgeElement.LeftContent>
<Image Source="../../Resources/Img/LeftMainContent/BorderElement_16x.png"/>
</controls:EdgeElement.LeftContent>
@@ -16,6 +16,13 @@ namespace HandyControlDemo.UserControl
public LeftMainContent()
{
InitializeComponent();
/*You have to ask me why I made Border special.
What drives me crazy is that if you don't do this,
the content of ListBoxItemBorder will always be 1 !
How amazing!
I wish someone could tell me why. */
ListBoxItemBorder.Content = Properties.Langs.Lang.Border;
}
private void TabControl_OnSelectionChanged(object sender, SelectionChangedEventArgs e)
@@ -26,7 +26,7 @@
<ToggleButton Width="128" Margin="0,0,0,10" Content="ToggleButton" Style="{StaticResource ToggleButtonPrimary}"/>
<ToggleButton Width="128" Margin="0,0,0,10" Style="{StaticResource ToggleButtonIcon}" controls:IconSwitchElement.Geometry="{StaticResource DeleteGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource DownGeometry}"/>
<ToggleButton Width="128" Margin="0,0,0,10" IsChecked="True" Content="ToggleButton" controls:IconElement.Geometry="{StaticResource ClockGeometry}" Style="{StaticResource ToggleButtonPrimary}"/>
<ToggleButton Margin="0,0,0,10" IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HiddenElement="True">
<ToggleButton Margin="0,0,0,10" IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HideUncheckedElement="True">
<controls:StatusSwitchElement.CheckedElement>
<Border Width="128" Height="30" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}">
<Ellipse Width="20" Height="20" Fill="{DynamicResource PrimaryBrush}" StrokeThickness="1" Stroke="{DynamicResource BorderBrush}"/>
@@ -77,7 +77,7 @@
<TextBlock TextAlignment="Center" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Style="{StaticResource TextBlockDefault}" Text="ToggleButtonIconTransparent"/>
</StackPanel>
<StackPanel>
<ToggleButton IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HiddenElement="True">
<ToggleButton IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HideUncheckedElement="True">
<controls:StatusSwitchElement.CheckedElement>
<Border Width="80" Height="30" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" Margin="5">
<Ellipse Width="20" Height="20" Fill="{DynamicResource PrimaryBrush}" StrokeThickness="1" Stroke="{DynamicResource BorderBrush}"/>
@@ -87,7 +87,7 @@
<Ellipse Width="20" Height="20" Fill="{DynamicResource BorderBrush}" StrokeThickness="1" Stroke="{DynamicResource BorderBrush}"/>
</Border>
</ToggleButton>
<ToggleButton IsEnabled="False" IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HiddenElement="True">
<ToggleButton IsEnabled="False" IsChecked="True" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HideUncheckedElement="True">
<controls:StatusSwitchElement.CheckedElement>
<Border Width="80" Height="30" CornerRadius="4" BorderThickness="1" BorderBrush="{DynamicResource BorderBrush}" Margin="5">
<Ellipse Width="20" Height="20" Fill="{DynamicResource PrimaryBrush}" StrokeThickness="1" Stroke="{DynamicResource BorderBrush}"/>
@@ -0,0 +1,32 @@
using System;
using System.Windows;
using GalaSoft.MvvmLight;
using HandyControl.Controls;
using HandyControl.Data;
#if netle40
using GalaSoft.MvvmLight.Command;
#else
using GalaSoft.MvvmLight.CommandWpf;
#endif
namespace HandyControlDemo.ViewModel
{
public class TabControlDemoViewModel : ViewModelBase
{
public RelayCommand<CancelRoutedEventArgs> ClosingCmd => new Lazy<RelayCommand<CancelRoutedEventArgs>>(() =>
new RelayCommand<CancelRoutedEventArgs>(Closing)).Value;
private void Closing(CancelRoutedEventArgs args)
{
Growl.Info($"{(args.OriginalSource as TabItem)?.Header} Closing");
}
public RelayCommand<RoutedEventArgs> ClosedCmd => new Lazy<RelayCommand<RoutedEventArgs>>(() =>
new RelayCommand<RoutedEventArgs>(Closed)).Value;
private void Closed(RoutedEventArgs args)
{
Growl.Info($"{(args.OriginalSource as TabItem)?.Header} Closed");
}
}
}
@@ -34,6 +34,7 @@ namespace HandyControlDemo.ViewModel
SimpleIoc.Default.Register<InteractiveDialogViewModel>();
SimpleIoc.Default.Register<BadgeDemoViewModel>();
SimpleIoc.Default.Register<SideMenuDemoViewModel>();
SimpleIoc.Default.Register<TabControlDemoViewModel>();
}
public static ViewModelLocator Instance => new Lazy<ViewModelLocator>(() =>
@@ -75,6 +76,8 @@ namespace HandyControlDemo.ViewModel
public SideMenuDemoViewModel SideMenuDemo => ServiceLocator.Current.GetInstance<SideMenuDemoViewModel>();
public TabControlDemoViewModel TabControlDemo => ServiceLocator.Current.GetInstance<TabControlDemoViewModel>();
#endregion
}
}
@@ -18,11 +18,11 @@ namespace HandyControl.Controls
/// <summary>
/// 是否隐藏元素
/// </summary>
public static readonly DependencyProperty HiddenElementProperty = DependencyProperty.RegisterAttached(
"HiddenElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(ValueBoxes.FalseBox));
public static readonly DependencyProperty HideUncheckedElementProperty = DependencyProperty.RegisterAttached(
"HideUncheckedElement", typeof(bool), typeof(StatusSwitchElement), new PropertyMetadata(ValueBoxes.FalseBox));
public static void SetHiddenElement(DependencyObject element, bool value) => element.SetValue(HiddenElementProperty, value);
public static void SetHideUncheckedElement(DependencyObject element, bool value) => element.SetValue(HideUncheckedElementProperty, value);
public static bool GetHiddenElement(DependencyObject element) => (bool) element.GetValue(HiddenElementProperty);
public static bool GetHideUncheckedElement(DependencyObject element) => (bool) element.GetValue(HideUncheckedElementProperty);
}
}
@@ -0,0 +1,106 @@
using System;
using System.Windows;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Tools;
using HandyControl.Tools.Interop;
namespace HandyControl.Controls
{
internal class ColorDropper
{
private bool _cursorIsSetted;
private Cursor _dropperCursor;
private readonly ColorPicker _colorPicker;
public ColorDropper(ColorPicker colorPicker)
{
_colorPicker = colorPicker;
}
public void Update(bool isShow)
{
if (isShow)
{
if (_dropperCursor == null)
{
var info = Application.GetResourceStream(new Uri("pack://application:,,,/HandyControl;Component/Resources/dropper.cur"));
if (info != null)
{
_dropperCursor = new Cursor(info.Stream);
}
}
if (_dropperCursor == null) return;
MouseHook.Start();
MouseHook.StatusChanged += MouseHook_StatusChanged;
}
else
{
Mouse.OverrideCursor = Cursors.Arrow;
MouseHook.Stop();
MouseHook.StatusChanged -= MouseHook_StatusChanged;
}
}
private void MouseHook_StatusChanged(object sender, MouseHookEventArgs e)
{
var window = System.Windows.Window.GetWindow(_colorPicker);
if (window == null)
{
UpdateCursor(false);
return;
}
if (!_colorPicker.IsMouseOver && window.IsMouseOver)
{
UpdateCursor(true);
if (e.Message == MouseHookMessageType.LeftButtonDown)
{
var brush = new SolidColorBrush(GetColorAt(e.Point.X, e.Point.Y));
_colorPicker.SelectedBrush = brush;
}
}
else
{
UpdateCursor(false);
}
}
private void UpdateCursor(bool isDropper)
{
if (isDropper)
{
Mouse.Captured?.ReleaseMouseCapture();
if (!_cursorIsSetted)
{
Mouse.OverrideCursor = _dropperCursor;
_cursorIsSetted = true;
}
}
else
{
if (_cursorIsSetted)
{
Mouse.OverrideCursor = Cursors.Arrow;
_cursorIsSetted = false;
}
}
}
public static Color GetColorAt(int x, int y)
{
var desk = UnsafeNativeMethods.GetDesktopWindow();
var dc = UnsafeNativeMethods.GetWindowDC(desk);
var a = (int)UnsafeNativeMethods.GetPixel(dc, x, y);
UnsafeNativeMethods.ReleaseDC(desk, dc);
return Color.FromArgb(255, (byte) ((a >> 0) & 0xff), (byte) ((a >> 8) & 0xff), (byte) ((a >> 16) & 0xff));
}
}
}
@@ -3,10 +3,12 @@ using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Interactivity;
using HandyControl.Tools;
using HandyControl.Tools.Extension;
namespace HandyControl.Controls
@@ -21,6 +23,7 @@ namespace HandyControl.Controls
[TemplatePart(Name = ElementSliderColor, Type = typeof(Panel))]
[TemplatePart(Name = ElementSliderOpacity, Type = typeof(Panel))]
[TemplatePart(Name = ElementPanelRgb, Type = typeof(Panel))]
[TemplatePart(Name = ElementButtonDropper, Type = typeof(ToggleButton))]
public class ColorPicker : Control, ISingleOpen
{
#region Constants
@@ -32,11 +35,16 @@ namespace HandyControl.Controls
private const string ElementSliderColor = "PART_SliderColor";
private const string ElementSliderOpacity = "PART_SliderOpacity";
private const string ElementPanelRgb = "PART_PanelRgb";
private const string ElementButtonDropper = "PART_ButtonDropper";
#endregion Constants
#region Data
private ColorDropper _colorDropper;
private ToggleButton _toggleButtonDropper;
private Panel _panelRgb;
private Border _borderColor;
@@ -53,6 +61,8 @@ namespace HandyControl.Controls
private bool _appliedTemplate;
private bool _disposed;
/// <summary>
/// 当前显示的颜色类型
/// </summary>
@@ -332,6 +342,11 @@ namespace HandyControl.Controls
}
}
~ColorPicker()
{
Dispose(false);
}
public ColorPicker()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Confirm, ButtonConfirm_OnClick));
@@ -361,6 +376,11 @@ namespace HandyControl.Controls
_sliderOpacity.ValueChanged -= SliderOpacity_OnValueChanged;
}
if (_toggleButtonDropper != null)
{
_toggleButtonDropper.Click -= ToggleButtonDropper_Click;
}
_panelColor?.Children.Clear();
_panelRgb?.RemoveHandler(NumericUpDown.ValueChangedEvent, new EventHandler<FunctionEventArgs<double>>(NumericUpDownRgb_OnValueChanged));
@@ -374,6 +394,7 @@ namespace HandyControl.Controls
_sliderColor = GetTemplateChild(ElementSliderColor) as Slider;
_sliderOpacity = GetTemplateChild(ElementSliderOpacity) as Slider;
_panelRgb = GetTemplateChild(ElementPanelRgb) as Panel;
_toggleButtonDropper = GetTemplateChild(ElementButtonDropper) as ToggleButton;
if (_sliderColor != null)
{
@@ -395,6 +416,11 @@ namespace HandyControl.Controls
collection.Add(behavior);
}
if (_toggleButtonDropper != null)
{
_toggleButtonDropper.Click += ToggleButtonDropper_Click;
}
_appliedTemplate = true;
if (_isLoaded)
{
@@ -428,7 +454,7 @@ namespace HandyControl.Controls
var button = new Button
{
Margin = new Thickness(0, 0, 12, 12),
Style = FindResource("ButtonCustom") as Style,
Style = ResourceHelper.GetResource<Style>(ResourceToken.ButtonCustom),
Content = new Border
{
Background = brush,
@@ -675,8 +701,35 @@ namespace HandyControl.Controls
private void ButtonCancel_OnClick(object sender, RoutedEventArgs e) => RaiseEvent(new RoutedEventArgs(CanceledEvent));
public void Dispose() => System.Windows.Window.GetWindow(this)?.Close();
private void ToggleButtonDropper_Click(object sender, RoutedEventArgs e)
{
if (_colorDropper == null)
{
_colorDropper = new ColorDropper(this);
}
// ReSharper disable once PossibleInvalidOperationException
_colorDropper.Update(_toggleButtonDropper.IsChecked.Value);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
Dispatcher.BeginInvoke(new Action(() =>
{
_colorDropper?.Update(false);
System.Windows.Window.GetWindow(this)?.Close();
}));
_disposed = true;
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
public bool CanDispose { get; } = true;
}
}
@@ -45,9 +45,9 @@ namespace HandyControl.Controls
{
return 0;
}
if (v >= ctl._uriList.Count)
if (v >= ctl._contentDic.Count)
{
return ctl._uriList.Count - 1;
return ctl._contentDic.Count - 1;
}
return v;
}
@@ -65,9 +65,9 @@ namespace HandyControl.Controls
"Loop", typeof(bool), typeof(CoverFlow), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 存储所有的资源标识符
/// 存储所有的内容
/// </summary>
private readonly Dictionary<int, Uri> _uriList = new Dictionary<int, Uri>();
private readonly Dictionary<int, object> _contentDic = new Dictionary<int, object>();
/// <summary>
/// 当前在显示范围内的项
@@ -154,12 +154,12 @@ namespace HandyControl.Controls
/// <summary>
/// 批量添加资源
/// </summary>
/// <param name="uriList"></param>
public void AddRange(List<Uri> uriList)
/// <param name="contentList"></param>
public void AddRange(IEnumerable<object> contentList)
{
foreach (var uri in uriList)
foreach (var content in contentList)
{
_uriList.Add(_uriList.Count, uri);
_contentDic.Add(_contentDic.Count, content);
}
}
@@ -167,13 +167,13 @@ namespace HandyControl.Controls
/// 添加一项资源
/// </summary>
/// <param name="uriString"></param>
public void Add(string uriString) => _uriList.Add(_uriList.Count, new Uri(uriString));
public void Add(string uriString) => _contentDic.Add(_contentDic.Count, new Uri(uriString));
/// <summary>
/// 添加一项资源
/// </summary>
/// <param name="uri"></param>
public void Add(Uri uri) => _uriList.Add(_uriList.Count, uri);
public void Add(Uri uri) => _contentDic.Add(_contentDic.Count, uri);
/// <summary>
/// 跳转
@@ -187,12 +187,12 @@ namespace HandyControl.Controls
if (e.Delta < 0)
{
var index = PageIndex + 1;
PageIndex = index >= _uriList.Count ? (Loop ? 0 : _uriList.Count - 1) : index;
PageIndex = index >= _contentDic.Count ? Loop ? 0 : _contentDic.Count - 1 : index;
}
else
{
var index = PageIndex - 1;
PageIndex = index < 0 ? (Loop ? _uriList.Count - 1 : 0) : index;
PageIndex = index < 0 ? Loop ? _contentDic.Count - 1 : 0 : index;
}
e.Handled = true;
@@ -273,7 +273,7 @@ namespace HandyControl.Controls
private void UpdateShowRange()
{
var newFirstShowIndex = Math.Max(PageIndex - MaxShowCountHalf, 0);
var newLastShowIndex = Math.Min(PageIndex + MaxShowCountHalf, _uriList.Count - 1);
var newLastShowIndex = Math.Min(PageIndex + MaxShowCountHalf, _contentDic.Count - 1);
if (_firstShowIndex < newFirstShowIndex)
{
@@ -294,7 +294,7 @@ namespace HandyControl.Controls
{
if (!_itemShowList.ContainsKey(i))
{
var cover = new CoverFlowItem(i, PageIndex, BitmapFrame.Create(_uriList[i]));
var cover = CreateCoverFlowItem(i, _contentDic[i]);
_itemShowList[i] = cover;
_visualParent.Children.Add(cover);
}
@@ -303,5 +303,21 @@ namespace HandyControl.Controls
_firstShowIndex = newFirstShowIndex;
_lastShowIndex = newLastShowIndex;
}
private CoverFlowItem CreateCoverFlowItem(int index, object content)
{
if (content is Uri uri)
{
return new CoverFlowItem(index, PageIndex, new Image
{
Source = BitmapFrame.Create(uri)
});
}
return new CoverFlowItem(index, PageIndex, new ContentControl
{
Content = content
});
}
}
}
@@ -18,14 +18,15 @@ namespace HandyControl.Controls
private readonly Model3DGroup _model3DGroup;
private readonly ImageSource _source;
private readonly UIElement _uiElement;
internal int Index { get; set; }
public CoverFlowItem(int itemIndex, int currentIndex, ImageSource source)
public CoverFlowItem(int itemIndex, int currentIndex, UIElement element)
{
Index = itemIndex;
_source = source;
_uiElement = element;
_uiElement.Measure(new Size(double.PositiveInfinity, double.PositiveInfinity));
_rotation3D = new AxisAngleRotation3D(new Vector3D(0, 1, 0), GetAngleByPos(currentIndex));
_transform3D = new TranslateTransform3D(GetXByPos(currentIndex), 0, GetZByPos(currentIndex));
@@ -35,7 +36,7 @@ namespace HandyControl.Controls
transformGroup.Children.Add(_transform3D);
_model3DGroup = new Model3DGroup();
_model3DGroup.Children.Add(new GeometryModel3D(CreateItemGeometry(), new DiffuseMaterial(new ImageBrush(_source))));
_model3DGroup.Children.Add(new GeometryModel3D(CreateItemGeometry(), new DiffuseMaterial(new VisualBrush(element))));
_model3DGroup.Transform = transformGroup;
Content = _model3DGroup;
@@ -103,8 +104,8 @@ namespace HandyControl.Controls
/// <returns></returns>
private Geometry3D CreateItemGeometry()
{
var sx = _source.Width > _source.Height ? 0 : 1 - _source.Width / _source.Height;
var sy = _source.Width < _source.Height ? 0 : 1 - _source.Height / _source.Width;
var sx = _uiElement.DesiredSize.Width > _uiElement.DesiredSize.Height ? 0 : 1 - _uiElement.DesiredSize.Width / _uiElement.DesiredSize.Height;
var sy = _uiElement.DesiredSize.Width < _uiElement.DesiredSize.Height ? 0 : 1 - _uiElement.DesiredSize.Height / _uiElement.DesiredSize.Width;
var p0 = new Point3D(-1 + sx, -1 + sy, 0);
var p1 = new Point3D(1 - sx, -1 + sy, 0);
@@ -8,7 +8,7 @@ namespace HandyControl.Controls
public class Col : ContentControl
{
public static readonly DependencyProperty LayoutProperty = DependencyProperty.Register(
"Layout", typeof(ColLayout), typeof(Col), new PropertyMetadata(new ColLayout()));
"Layout", typeof(ColLayout), typeof(Col), new PropertyMetadata(default(ColLayout)));
public ColLayout Layout
{
@@ -17,7 +17,7 @@ namespace HandyControl.Controls
}
public static readonly DependencyProperty OffsetProperty = DependencyProperty.Register(
"Offset", typeof(int), typeof(Col), new PropertyMetadata(default(int)));
"Offset", typeof(int), typeof(Col), new PropertyMetadata(ValueBoxes.Int0Box));
public int Offset
{
@@ -25,18 +25,55 @@ namespace HandyControl.Controls
set => SetValue(OffsetProperty, value);
}
public static readonly DependencyProperty SpanProperty = DependencyProperty.Register(
"Span", typeof(int), typeof(Col), new PropertyMetadata(24), OnSpanValidate);
private static bool OnSpanValidate(object value)
{
var v = (int)value;
return v >= 1 || v <= 24;
}
public int Span
{
get => (int) GetValue(SpanProperty);
set => SetValue(SpanProperty, value);
}
internal int GetLayoutCellCount(ColLayoutStatus status)
{
switch (status)
var result = 0;
if (Layout != null)
{
case ColLayoutStatus.Xs: return Layout.Xs;
case ColLayoutStatus.Sm: return Layout.Sm;
case ColLayoutStatus.Md: return Layout.Md;
case ColLayoutStatus.Lg: return Layout.Lg;
case ColLayoutStatus.Xl: return Layout.Xl;
case ColLayoutStatus.Xxl: return Layout.Xxl;
default: return 0;
switch (status)
{
case ColLayoutStatus.Xs:
result = Layout.Xs;
break;
case ColLayoutStatus.Sm:
result = Layout.Sm;
break;
case ColLayoutStatus.Md:
result = Layout.Md;
break;
case ColLayoutStatus.Lg:
result = Layout.Lg;
break;
case ColLayoutStatus.Xl:
result = Layout.Xl;
break;
case ColLayoutStatus.Xxl:
result = Layout.Xxl;
break;
}
}
else
{
result = Span;
}
return result;
}
}
}
@@ -3,6 +3,7 @@ using System.Linq;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
{
@@ -10,8 +11,14 @@ namespace HandyControl.Controls
{
private ColLayoutStatus _layoutStatus;
private double _maxChildDesiredHeight;
public static readonly DependencyProperty GutterProperty = DependencyProperty.Register(
"Gutter", typeof(double), typeof(Row), new PropertyMetadata(default(double)));
"Gutter", typeof(double), typeof(Row), new PropertyMetadata(ValueBoxes.Double0Box, null, OnGutterCoerce), OnGutterValidate);
private static object OnGutterCoerce(DependencyObject d, object basevalue) => OnGutterValidate(basevalue) ? basevalue : .0;
private static bool OnGutterValidate(object value) => ValidateHelper.IsInRangeOfPosDouble(value, true);
public double Gutter
{
@@ -21,25 +28,24 @@ namespace HandyControl.Controls
protected override Size MeasureOverride(Size constraint)
{
var itemWidth = constraint.Width / ColLayout.ColMaxCellCount;
var totalCellCount = 0;
var totalRowCount = 1;
var maxChildDesiredHeight = .0;
var gutterHalf = Gutter / 2;
for (int i = 0, count = InternalChildren.Count; i < count; ++i)
foreach (var child in InternalChildren.OfType<Col>())
{
var child = InternalChildren[i];
child.Margin = new Thickness(gutterHalf);
child.Measure(constraint);
var childDesiredSize = child.DesiredSize;
if (maxChildDesiredHeight < childDesiredSize.Height)
if (_maxChildDesiredHeight < childDesiredSize.Height)
{
maxChildDesiredHeight = childDesiredSize.Height;
_maxChildDesiredHeight = childDesiredSize.Height;
}
}
var childBounds = new Rect(0, 0, 0, maxChildDesiredHeight);
var itemWidth = constraint.Width / ColLayout.ColMaxCellCount;
var childBounds = new Rect(-gutterHalf, -gutterHalf, 0, _maxChildDesiredHeight);
_layoutStatus = ColLayout.GetLayoutStatus(constraint.Width);
foreach (var child in InternalChildren.OfType<Col>())
@@ -49,19 +55,48 @@ namespace HandyControl.Controls
if (totalCellCount > ColLayout.ColMaxCellCount)
{
childBounds.X = 0;
childBounds.Y += maxChildDesiredHeight;
childBounds.X = -gutterHalf;
childBounds.Y += _maxChildDesiredHeight;
totalCellCount = cellCount;
totalRowCount++;
}
var childWidth = cellCount * itemWidth;
childBounds.Width = childWidth;
childBounds.X += childWidth + child.Offset * itemWidth;
}
return new Size(0, _maxChildDesiredHeight * totalRowCount - Gutter);
}
protected override Size ArrangeOverride(Size finalSize)
{
var totalCellCount = 0;
var gutterHalf = Gutter / 2;
var itemWidth = (finalSize.Width + Gutter) / ColLayout.ColMaxCellCount;
var childBounds = new Rect(-gutterHalf, -gutterHalf, 0, _maxChildDesiredHeight);
_layoutStatus = ColLayout.GetLayoutStatus(finalSize.Width);
foreach (var child in InternalChildren.OfType<Col>())
{
var cellCount = child.GetLayoutCellCount(_layoutStatus);
totalCellCount += cellCount;
var childWidth = cellCount * itemWidth;
childBounds.Width = childWidth;
childBounds.X += child.Offset * itemWidth;
if (totalCellCount > ColLayout.ColMaxCellCount)
{
childBounds.X = -gutterHalf;
childBounds.Y += _maxChildDesiredHeight;
totalCellCount = cellCount;
}
child.Arrange(childBounds);
childBounds.X += childWidth;
}
return new Size(constraint.Width, maxChildDesiredHeight * totalRowCount);
return finalSize;
}
}
}
@@ -1,15 +1,44 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
#if netle40
using System.Windows.Threading;
#endif
using HandyControl.Data;
using HandyControl.Interactivity;
namespace HandyControl.Controls
{
/// <inheritdoc cref="IDataInput" />
[TemplatePart(Name = AutoCompletePanel, Type = typeof(Panel))]
[TemplatePart(Name = EditableTextBox, Type = typeof(System.Windows.Controls.TextBox))]
[TemplatePart(Name = AutoPopupAutoComplete, Type = typeof(Popup))]
public class ComboBox : System.Windows.Controls.ComboBox, IDataInput
{
#if netle40
private string _searchText;
private DispatcherTimer _autoCompleteTimer;
#endif
private bool _isAutoCompleteAction = true;
private Panel _autoCompletePanel;
private System.Windows.Controls.TextBox _editableTextBox;
private Popup _autoPopupAutoComplete;
private const string AutoCompletePanel = "PART_AutoCompletePanel";
private const string AutoPopupAutoComplete = "PART_Popup_AutoComplete";
private const string EditableTextBox = "PART_EditableTextBox";
public ComboBox()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
@@ -21,23 +50,125 @@ namespace HandyControl.Controls
}));
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
public override void OnApplyTemplate()
{
if (_editableTextBox != null)
{
BindingOperations.ClearBinding(_editableTextBox, System.Windows.Controls.TextBox.TextProperty);
_editableTextBox.GotFocus -= EditableTextBox_GotFocus;
_editableTextBox.LostFocus -= EditableTextBox_LostFocus;
}
base.OnApplyTemplate();
if (IsEditable)
{
_editableTextBox = GetTemplateChild(EditableTextBox) as System.Windows.Controls.TextBox;
if (_editableTextBox != null)
{
_editableTextBox.TextChanged += EditableTextBox_TextChanged;
if (AutoComplete)
{
#if netle40
_autoCompleteTimer = new DispatcherTimer
{
Interval = TimeSpan.FromMilliseconds(500)
};
_autoCompleteTimer.Tick += AutoCompleteTimer_Tick;
#endif
_autoPopupAutoComplete = GetTemplateChild(AutoPopupAutoComplete) as Popup;
_autoCompletePanel = GetTemplateChild(AutoCompletePanel) as Panel;
_editableTextBox.SetBinding(System.Windows.Controls.TextBox.TextProperty, new Binding(SearchTextProperty.Name)
{
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged,
Mode = BindingMode.OneWayToSource,
#if !netle40
Delay = 500,
#endif
Source = this
});
_editableTextBox.GotFocus += EditableTextBox_GotFocus;
_editableTextBox.LostFocus += EditableTextBox_LostFocus;
}
}
}
}
#if netle40
private void AutoCompleteTimer_Tick(object sender, EventArgs e)
{
UpdateSearchItems(_searchText);
_autoCompleteTimer.Stop();
}
#endif
private void EditableTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
base.OnSelectionChanged(e);
VerifyData();
}
private void EditableTextBox_LostFocus(object sender, RoutedEventArgs e)
{
if (_autoPopupAutoComplete != null)
{
_autoPopupAutoComplete.IsOpen = false;
}
}
#if !netle40
protected override void OnDropDownClosed(EventArgs e)
{
base.OnDropDownClosed(e);
_isAutoCompleteAction = false;
}
#endif
private void EditableTextBox_GotFocus(object sender, RoutedEventArgs e)
{
if (_autoPopupAutoComplete != null && _editableTextBox != null &&
!string.IsNullOrEmpty(_editableTextBox.Text))
{
_autoPopupAutoComplete.IsOpen = true;
}
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
_isAutoCompleteAction = false;
base.OnSelectionChanged(e);
VerifyData();
#if netle40
_isAutoCompleteAction = true;
#endif
}
/// <summary>
/// 数据验证委托
/// </summary>
public Func<string, OperationResult<bool>> VerifyFunc { get; set; }
/// <summary>
/// 数据搜索委托
/// </summary>
public Func<ItemCollection, object, IEnumerable<object>> SearchFunc { get; set; }
/// <summary>
/// 数据是否错误
/// </summary>
public static readonly DependencyProperty IsErrorProperty = DependencyProperty.Register(
"IsError", typeof(bool), typeof(ComboBox), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 数据是否错误
/// </summary>
public bool IsError
{
get => (bool) GetValue(IsErrorProperty);
get => (bool)GetValue(IsErrorProperty);
set => SetValue(IsErrorProperty, value);
}
@@ -47,12 +178,18 @@ namespace HandyControl.Controls
public static readonly DependencyProperty ErrorStrProperty = DependencyProperty.Register(
"ErrorStr", typeof(string), typeof(ComboBox), new PropertyMetadata(default(string)));
/// <summary>
/// 错误提示
/// </summary>
public string ErrorStr
{
get => (string) GetValue(ErrorStrProperty);
get => (string)GetValue(ErrorStrProperty);
set => SetValue(ErrorStrProperty, value);
}
/// <summary>
/// 文本类型
/// </summary>
public static readonly DependencyPropertyKey TextTypePropertyKey =
DependencyProperty.RegisterReadOnly("TextType", typeof(TextType), typeof(ComboBox),
new PropertyMetadata(default(TextType)));
@@ -62,9 +199,12 @@ namespace HandyControl.Controls
/// </summary>
public static readonly DependencyProperty TextTypeProperty = TextTypePropertyKey.DependencyProperty;
/// <summary>
/// 文本类型
/// </summary>
public TextType TextType
{
get => (TextType) GetValue(TextTypeProperty);
get => (TextType)GetValue(TextTypeProperty);
set => SetValue(TextTypeProperty, value);
}
@@ -74,23 +214,151 @@ namespace HandyControl.Controls
public static readonly DependencyProperty ShowClearButtonProperty = DependencyProperty.Register(
"ShowClearButton", typeof(bool), typeof(ComboBox), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 是否显示清除按钮
/// </summary>
public bool ShowClearButton
{
get => (bool) GetValue(ShowClearButtonProperty);
get => (bool)GetValue(ShowClearButtonProperty);
set => SetValue(ShowClearButtonProperty, value);
}
/// <summary>
/// 是否自动完成输入
/// </summary>
public static readonly DependencyProperty AutoCompleteProperty = DependencyProperty.Register(
"AutoComplete", typeof(bool), typeof(ComboBox), new PropertyMetadata(ValueBoxes.FalseBox, OnAutoCompleteChanged));
private static void OnAutoCompleteChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (ComboBox)d;
if (ctl._editableTextBox != null)
{
ctl.UpdateSearchItems(ctl._editableTextBox.Text);
}
}
/// <summary>
/// 更新搜索的项目
/// </summary>
/// <param name="key"></param>
private void UpdateSearchItems(string key)
{
if (_editableTextBox != null && _autoPopupAutoComplete != null)
{
_autoPopupAutoComplete.IsOpen = !string.IsNullOrEmpty(key);
_autoCompletePanel.Children.Clear();
if (SearchFunc == null)
{
if (!string.IsNullOrEmpty(key))
{
foreach (var item in Items)
{
var content = item?.ToString();
if (content == null) continue;
if (!content.Contains(key)) continue;
_autoCompletePanel.Children.Add(CreateSearchItem(item));
}
}
}
else
{
foreach (var item in SearchFunc.Invoke(Items, key))
{
_autoCompletePanel.Children.Add(CreateSearchItem(item));
}
}
}
}
private ComboBoxItem CreateSearchItem(object content)
{
var item = new ComboBoxItem
{
Content = content,
Style = ItemContainerStyle,
ContentTemplate = ItemTemplate
};
item.PreviewMouseLeftButtonDown += AutoCompleteItem_PreviewMouseLeftButtonDown;
return item;
}
private void AutoCompleteItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (sender is ComboBoxItem comboBoxItem)
{
if (_autoPopupAutoComplete != null)
{
_autoPopupAutoComplete.IsOpen = false;
}
_isAutoCompleteAction = false;
SelectedValue = comboBoxItem.Content;
}
}
/// <summary>
/// 搜索文本
/// </summary>
internal static readonly DependencyProperty SearchTextProperty = DependencyProperty.Register(
"SearchText", typeof(string), typeof(ComboBox), new PropertyMetadata(default(string), OnSearchTextChanged));
private static void OnSearchTextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (ComboBox)d;
if (ctl._isAutoCompleteAction)
{
#if netle40
ctl._searchText = e.NewValue as string;
ctl._autoCompleteTimer.Stop();
ctl._autoCompleteTimer.Start();
#else
ctl.UpdateSearchItems(e.NewValue as string);
#endif
}
ctl._isAutoCompleteAction = true;
}
/// <summary>
/// 搜索文本
/// </summary>
internal string SearchText
{
get => (string)GetValue(SearchTextProperty);
set => SetValue(SearchTextProperty, value);
}
/// <summary>
/// 是否自动完成输入
/// </summary>
public bool AutoComplete
{
get => (bool)GetValue(AutoCompleteProperty);
set => SetValue(AutoCompleteProperty, value);
}
/// <summary>
/// 验证数据
/// </summary>
/// <returns></returns>
public virtual bool VerifyData()
{
OperationResult<bool> result;
var value = _editableTextBox == null ? Text : _editableTextBox.Text;
if (VerifyFunc != null)
{
result = VerifyFunc.Invoke(Text);
result = VerifyFunc.Invoke(value);
}
else
{
if (!string.IsNullOrEmpty(Text))
if (!string.IsNullOrEmpty(value))
{
result = OperationResult.Success();
}
@@ -99,15 +99,6 @@ namespace HandyControl.Controls
set => SetValue(DateTimeFormatProperty, value);
}
public static readonly DependencyProperty ClockStyleProperty = DependencyProperty.Register(
"ClockStyle", typeof(Style), typeof(DateTimePicker), new PropertyMetadata(default(Style)));
public Style ClockStyle
{
get => (Style) GetValue(ClockStyleProperty);
set => SetValue(ClockStyleProperty, value);
}
public static readonly DependencyProperty CalendarStyleProperty = DependencyProperty.Register(
"CalendarStyle", typeof(Style), typeof(DateTimePicker), new PropertyMetadata(default(Style)));
@@ -34,8 +34,6 @@ namespace HandyControl.Controls
#region Data
private Clock _clock;
private string _defaultText;
private ButtonBase _dropDownButton;
@@ -79,7 +77,7 @@ namespace HandyControl.Controls
public TimePicker()
{
InitClock();
Clock = new Clock();
CommandBindings.Add(new CommandBinding(ControlCommands.Clear, (s, e) =>
{
ClearValue(SelectedTimeProperty);
@@ -103,18 +101,6 @@ namespace HandyControl.Controls
#endregion TimeFormat
#region ClockStyle
public Style ClockStyle
{
get => (Style)GetValue(ClockStyleProperty);
set => SetValue(ClockStyleProperty, value);
}
public static readonly DependencyProperty ClockStyleProperty = DependencyProperty.Register("ClockStyle", typeof(Style), typeof(TimePicker));
#endregion CalendarStyle
#region DisplayTime
public DateTime DisplayTime
@@ -133,8 +119,8 @@ namespace HandyControl.Controls
private static object CoerceDisplayTime(DependencyObject d, object value)
{
var dp = (TimePicker)d;
dp._clock.DisplayTime = (DateTime)value;
return dp._clock.DisplayTime;
dp.Clock.DisplayTime = (DateTime)value;
return dp.Clock.DisplayTime;
}
#endregion DisplayTime
@@ -170,7 +156,7 @@ namespace HandyControl.Controls
dp.Dispatcher.BeginInvoke(DispatcherPriority.Input, (Action)delegate
{
dp._clock.Focus();
dp.Clock.Focus();
});
}
}
@@ -212,8 +198,8 @@ namespace HandyControl.Controls
private static object CoerceSelectedTime(DependencyObject d, object value)
{
var dp = (TimePicker)d;
dp._clock.SelectedTime = (DateTime?)value;
return dp._clock.SelectedTime;
dp.Clock.SelectedTime = (DateTime?)value;
return dp.Clock.SelectedTime;
}
#endregion SelectedDate
@@ -306,6 +292,35 @@ namespace HandyControl.Controls
set => SetValue(ShowClearButtonProperty, value);
}
public static readonly DependencyProperty ClockProperty = DependencyProperty.Register(
"Clock", typeof(ClockBase), typeof(TimePicker), new FrameworkPropertyMetadata(default(Clock), FrameworkPropertyMetadataOptions.NotDataBindable, OnClockChanged));
private static void OnClockChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (TimePicker) d;
var oldClock = e.OldValue as ClockBase;
var newClock = e.NewValue as ClockBase;
if (oldClock != null)
{
oldClock.SelectedTimeChanged -= ctl.Clock_SelectedTimeChanged;
oldClock.Confirmed -= ctl.Clock_Confirmed;
}
if (newClock != null)
{
newClock.ShowConfirmButton = true;
newClock.SelectedTimeChanged += ctl.Clock_SelectedTimeChanged;
newClock.Confirmed += ctl.Clock_Confirmed;
}
}
public ClockBase Clock
{
get => (ClockBase) GetValue(ClockProperty);
set => SetValue(ClockProperty, value);
}
#endregion Public Properties
#region Public Methods
@@ -374,7 +389,7 @@ namespace HandyControl.Controls
_popUp.PreviewMouseLeftButtonDown += PopUp_PreviewMouseLeftButtonDown;
_popUp.Opened += PopUp_Opened;
_popUp.Closed += PopUp_Closed;
_popUp.Child = _clock;
_popUp.Child = Clock;
if (IsDropDownOpen)
{
@@ -439,20 +454,7 @@ namespace HandyControl.Controls
throw new Exception();
}
private void InitClock()
{
_clock = new Clock
{
ShowConfirmButton = true
};
_clock.SelectedTimeChanged += Clock_SelectedTimeChanged;
_clock.Confirmed += Clock_Confirmed;
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e)
{
SetSelectedTime();
}
private void TextBox_LostFocus(object sender, RoutedEventArgs e) => SetSelectedTime();
private void SetIsHandlerSuspended(DependencyProperty property, bool value)
{
@@ -560,7 +562,7 @@ namespace HandyControl.Controls
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.TrueBox);
}
_clock?.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
Clock?.MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
OnClockOpened(new RoutedEventArgs());
}
@@ -572,7 +574,7 @@ namespace HandyControl.Controls
SetCurrentValue(IsDropDownOpenProperty, ValueBoxes.FalseBox);
}
if (_clock.IsKeyboardFocusWithin)
if (Clock.IsKeyboardFocusWithin)
{
MoveFocus(new TraversalRequest(FocusNavigationDirection.First));
}
@@ -15,7 +15,7 @@ namespace HandyControl.Controls
private bool _isLoaded;
/// <summary>
/// 故事版
/// 故事板
/// </summary>
private Storyboard _storyboard;
@@ -114,7 +114,8 @@ namespace HandyControl.Controls
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentVerticalOffsetProperty, animation);
BeginAnimation(CurrentVerticalOffsetProperty, animation, HandoffBehavior.Compose);
}
internal void ScrollToHorizontalOffsetInternal(double offset, double milliseconds = 500)
@@ -131,7 +132,8 @@ namespace HandyControl.Controls
_isRunning = false;
};
_isRunning = true;
BeginAnimation(CurrentHorizontalOffsetProperty, animation);
BeginAnimation(CurrentHorizontalOffsetProperty, animation, HandoffBehavior.Compose);
}
protected override HitTestResult HitTestCore(PointHitTestParameters hitTestParameters) =>
@@ -150,7 +152,7 @@ namespace HandyControl.Controls
public static bool GetIsEnableInertia(DependencyObject element)
{
return (bool) element.GetValue(IsEnableInertiaProperty);
return (bool)element.GetValue(IsEnableInertiaProperty);
}
/// <summary>
@@ -158,7 +160,7 @@ namespace HandyControl.Controls
/// </summary>
public bool IsEnableInertia
{
get => (bool)GetValue(IsEnableInertiaProperty);
get => (bool) GetValue(IsEnableInertiaProperty);
set => SetValue(IsEnableInertiaProperty, value);
}
@@ -173,7 +175,7 @@ namespace HandyControl.Controls
/// </summary>
public bool IsPenetrating
{
get => (bool)GetValue(IsPenetratingProperty);
get => (bool) GetValue(IsPenetratingProperty);
set => SetValue(IsPenetratingProperty, value);
}
@@ -190,7 +192,7 @@ namespace HandyControl.Controls
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
private static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
internal static readonly DependencyProperty CurrentVerticalOffsetProperty = DependencyProperty.Register(
"CurrentVerticalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentVerticalOffsetChanged));
private static void OnCurrentVerticalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -204,7 +206,7 @@ namespace HandyControl.Controls
/// <summary>
/// 当前垂直滚动偏移
/// </summary>
private double CurrentVerticalOffset
internal double CurrentVerticalOffset
{
// ReSharper disable once UnusedMember.Local
get => (double) GetValue(CurrentVerticalOffsetProperty);
@@ -214,7 +216,7 @@ namespace HandyControl.Controls
/// <summary>
/// 当前水平滚动偏移
/// </summary>
public static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register(
internal static readonly DependencyProperty CurrentHorizontalOffsetProperty = DependencyProperty.Register(
"CurrentHorizontalOffset", typeof(double), typeof(ScrollViewer), new PropertyMetadata(ValueBoxes.Double0Box, OnCurrentHorizontalOffsetChanged));
private static void OnCurrentHorizontalOffsetChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
@@ -228,7 +230,7 @@ namespace HandyControl.Controls
/// <summary>
/// 当前水平滚动偏移
/// </summary>
public double CurrentHorizontalOffset
internal double CurrentHorizontalOffset
{
get => (double) GetValue(CurrentHorizontalOffsetProperty);
set => SetValue(CurrentHorizontalOffsetProperty, value);
@@ -15,11 +15,9 @@ namespace HandyControl.Controls
protected override Size MeasureOverride(Size availableSize)
{
var maxSize = new Size();
var children = InternalChildren;
for (int i = 0, count = children.Count; i < count; ++i)
foreach (UIElement child in InternalChildren)
{
var child = children[i];
if (child != null)
{
child.Measure(availableSize);
@@ -1,8 +1,10 @@
using System;
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using HandyControl.Data;
using HandyControl.Tools.Extension;
@@ -10,16 +12,31 @@ namespace HandyControl.Controls
{
[TemplatePart(Name = OverflowButtonKey, Type = typeof(ContextMenuToggleButton))]
[TemplatePart(Name = HeaderPanelKey, Type = typeof(TabPanel))]
[TemplatePart(Name = OverflowScrollviewer, Type = typeof(ScrollViewer))]
[TemplatePart(Name = ScrollButtonLeft, Type = typeof(Button))]
[TemplatePart(Name = ScrollButtonRight, Type = typeof(Button))]
public class TabControl : System.Windows.Controls.TabControl
{
private const string OverflowButtonKey = "PART_OverflowButton";
private const string HeaderPanelKey = "PART_HeaderPanel";
private const string OverflowScrollviewer = "PART_OverflowScrollviewer";
private const string ScrollButtonLeft = "PART_ScrollButtonLeft";
private const string ScrollButtonRight = "PART_ScrollButtonRight";
private ContextMenuToggleButton _buttonOverflow;
private TabPanel _headerPanel;
private ScrollViewer _scrollViewerOverflow;
private Button _buttonScrollLeft;
private Button _buttonScrollRight;
/// <summary>
/// 是否为内部操作
/// </summary>
@@ -115,6 +132,51 @@ namespace HandyControl.Controls
set => SetValue(TabItemHeightProperty, value);
}
/// <summary>
/// 是否可以滚动
/// </summary>
public static readonly DependencyProperty IsScrollableProperty = DependencyProperty.Register(
"IsScrollable", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 是否可以滚动
/// </summary>
public bool IsScrollable
{
get => (bool) GetValue(IsScrollableProperty);
set => SetValue(IsScrollableProperty, value);
}
/// <summary>
/// 是否显示溢出按钮
/// </summary>
public static readonly DependencyProperty ShowOverflowButtonProperty = DependencyProperty.Register(
"ShowOverflowButton", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.TrueBox));
/// <summary>
/// 是否显示溢出按钮
/// </summary>
public bool ShowOverflowButton
{
get => (bool) GetValue(ShowOverflowButtonProperty);
set => SetValue(ShowOverflowButtonProperty, value);
}
/// <summary>
/// 是否显示滚动按钮
/// </summary>
public static readonly DependencyProperty ShowScrollButtonProperty = DependencyProperty.Register(
"ShowScrollButton", typeof(bool), typeof(TabControl), new PropertyMetadata(ValueBoxes.FalseBox));
/// <summary>
/// 是否显示滚动按钮
/// </summary>
public bool ShowScrollButton
{
get => (bool) GetValue(ShowScrollButtonProperty);
set => SetValue(ShowScrollButtonProperty, value);
}
/// <summary>
/// 可见的标签数量
/// </summary>
@@ -133,7 +195,7 @@ namespace HandyControl.Controls
if (!IsEnableTabFill)
{
_itemShowCount = (int)(ActualWidth / TabItemWidth);
_buttonOverflow.Show(Items.Count > 0 && Items.Count >= _itemShowCount);
_buttonOverflow?.Show(ShowOverflowButton && Items.Count > 0 && Items.Count >= _itemShowCount);
}
if (IsInternalAction)
@@ -163,64 +225,130 @@ namespace HandyControl.Controls
public override void OnApplyTemplate()
{
if (_buttonOverflow != null)
{
if (_buttonOverflow.Menu != null)
{
_buttonOverflow.Menu.Closed -= Menu_Closed;
_buttonOverflow.Menu = null;
}
_buttonOverflow.Click -= ButtonOverflow_Click;
}
if (_buttonScrollLeft != null) _buttonScrollLeft.Click -= ButtonScrollLeft_Click;
if (_buttonScrollRight != null) _buttonScrollRight.Click -= ButtonScrollRight_Click;
base.OnApplyTemplate();
_headerPanel = Template.FindName(HeaderPanelKey, this) as TabPanel;
_headerPanel = GetTemplateChild(HeaderPanelKey) as TabPanel;
if (IsEnableTabFill) return;
_buttonOverflow = Template.FindName(OverflowButtonKey, this) as ContextMenuToggleButton;
_buttonOverflow = GetTemplateChild(OverflowButtonKey) as ContextMenuToggleButton;
_scrollViewerOverflow = GetTemplateChild(OverflowScrollviewer) as ScrollViewer;
_buttonScrollLeft = GetTemplateChild(ScrollButtonLeft) as Button;
_buttonScrollRight = GetTemplateChild(ScrollButtonRight) as Button;
if (_buttonScrollLeft != null) _buttonScrollLeft.Click += ButtonScrollLeft_Click;
if (_buttonScrollRight != null) _buttonScrollRight.Click += ButtonScrollRight_Click;
if (_buttonOverflow != null)
{
_itemShowCount = (int)(ActualWidth / TabItemWidth);
_buttonOverflow.Show(Items.Count > 0 && Items.Count >= _itemShowCount);
_buttonOverflow.Show(ShowOverflowButton && Items.Count > 0 && Items.Count >= _itemShowCount);
var menu = new ContextMenu
{
Placement = PlacementMode.Bottom,
PlacementTarget = _buttonOverflow
};
menu.Closed += (s, e) => _buttonOverflow.IsChecked = false;
menu.Closed += Menu_Closed;
_buttonOverflow.Menu = menu;
_buttonOverflow.Click += (s, e) =>
_buttonOverflow.Click += ButtonOverflow_Click;
}
}
private void Menu_Closed(object sender, RoutedEventArgs e) => _buttonOverflow.IsChecked = false;
private void ButtonScrollRight_Click(object sender, RoutedEventArgs e) =>
_scrollViewerOverflow.ScrollToHorizontalOffsetInternal(Math.Min(
_scrollViewerOverflow.CurrentHorizontalOffset + TabItemWidth, _scrollViewerOverflow.ScrollableWidth));
private void ButtonScrollLeft_Click(object sender, RoutedEventArgs e) =>
_scrollViewerOverflow.ScrollToHorizontalOffsetInternal(Math.Max(
_scrollViewerOverflow.CurrentHorizontalOffset - TabItemWidth, 0));
private void ButtonOverflow_Click(object sender, RoutedEventArgs e)
{
if (_buttonOverflow.IsChecked == true)
{
_buttonOverflow.Menu.Items.Clear();
foreach (TabItem item in Items)
{
if (_buttonOverflow.IsChecked == true)
var menuItem = new MenuItem
{
_buttonOverflow.Menu.Items.Clear();
foreach (TabItem item in Items)
Header = item.Header,
Width = TabItemWidth,
IsChecked = item.IsSelected,
IsCheckable = true
};
menuItem.Click += delegate
{
_buttonOverflow.IsChecked = false;
var index = Items.IndexOf(item);
if (index >= _itemShowCount)
{
var menuItem = new MenuItem
Items.Remove(item);
Items.Insert(0, item);
if (IsEnableAnimation)
{
Header = item.Header,
Width = TabItemWidth,
IsChecked = item.IsSelected,
IsCheckable = true
};
menuItem.Click += delegate
_headerPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
}
else
{
_buttonOverflow.IsChecked = false;
var index = Items.IndexOf(item);
if (index >= _itemShowCount)
{
Items.Remove(item);
Items.Insert(0, item);
if (IsEnableAnimation)
{
_headerPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
}
else
{
_headerPanel.FluidMoveDuration = new Duration(TimeSpan.FromSeconds(0));
}
_headerPanel.ForceUpdate = true;
_headerPanel.Measure(new Size(_headerPanel.DesiredSize.Width, ActualHeight));
_headerPanel.ForceUpdate = false;
}
item.IsSelected = true;
};
_buttonOverflow.Menu.Items.Add(menuItem);
_headerPanel.FluidMoveDuration = new Duration(TimeSpan.FromSeconds(0));
}
_headerPanel.ForceUpdate = true;
_headerPanel.Measure(new Size(_headerPanel.DesiredSize.Width, ActualHeight));
_headerPanel.ForceUpdate = false;
}
item.IsSelected = true;
};
_buttonOverflow.Menu.Items.Add(menuItem);
}
}
}
internal double GetHorizontalOffset() => _scrollViewerOverflow?.CurrentHorizontalOffset ?? 0;
internal void UpdateScroll() => _scrollViewerOverflow?.RaiseEvent(new MouseWheelEventArgs(Mouse.PrimaryDevice, Environment.TickCount, 0)
{
RoutedEvent = MouseWheelEvent
});
internal void CloseAllItems() => CloseOtherItems(null);
internal void CloseOtherItems(TabItem currentItem)
{
IsInternalAction = true;
var enumerator = ((IEnumerable)Items).GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
if (!Equals(item, currentItem) && item != null)
{
var argsClosing = new CancelRoutedEventArgs(TabItem.ClosingEvent, item);
var elment = item as UIElement;
if (elment != null)
{
elment.RaiseEvent(argsClosing);
if (argsClosing.Cancel) return;
}
};
elment?.RaiseEvent(new RoutedEventArgs(TabItem.ClosedEvent, item));
Items.Remove(item);
enumerator = ((IEnumerable)Items).GetEnumerator();
}
}
}
}
@@ -1,10 +1,10 @@
using System;
using System.Collections;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using HandyControl.Data;
using HandyControl.Interactivity;
using HandyControl.Tools;
@@ -87,6 +87,11 @@ namespace HandyControl.Controls
/// </summary>
private int _currentIndex;
/// <summary>
/// 标签容器横向滚动距离
/// </summary>
private double _scrollHorizontalOffset;
/// <summary>
/// 标签容器
/// </summary>
@@ -125,26 +130,11 @@ namespace HandyControl.Controls
public TabItem()
{
CommandBindings.Add(new CommandBinding(ControlCommands.Close, Close));
CommandBindings.Add(new CommandBinding(ControlCommands.CloseAll, (s, e) =>
{
TabControlParent.IsInternalAction = true;
TabControlParent.Items.Clear();
}));
CommandBindings.Add(new CommandBinding(ControlCommands.CloseOther, (s, e) =>
{
TabControlParent.IsInternalAction = true;
var enumerator = ((IEnumerable)TabControlParent.Items).GetEnumerator();
while (enumerator.MoveNext())
{
var item = enumerator.Current;
if (!Equals(item) && item != null)
{
TabControlParent.Items.Remove(item);
enumerator = ((IEnumerable)TabControlParent.Items).GetEnumerator();
}
}
}));
CommandBindings.Add(new CommandBinding(ControlCommands.Close, (s, e) => Close()));
CommandBindings.Add(new CommandBinding(ControlCommands.CloseAll,
(s, e) => { TabControlParent.CloseAllItems(); }));
CommandBindings.Add(new CommandBinding(ControlCommands.CloseOther,
(s, e) => { TabControlParent.CloseOtherItems(this); }));
}
private TabControl TabControlParent => new Lazy<TabControl>(() => ItemsControl.ItemsControlFromItemContainer(this) as TabControl).Value;
@@ -156,11 +146,12 @@ namespace HandyControl.Controls
Focus();
}
/// <summary>
/// 关闭
/// </summary>
private void Close(object sender, RoutedEventArgs e)
internal void Close()
{
var argsClosing = new CancelRoutedEventArgs(ClosingEvent, this);
RaiseEvent(argsClosing);
if (argsClosing.Cancel) return;
if (TabControlParent.IsEnableAnimation)
{
TabPanel.ClearValue(TabPanel.FluidMoveDurationProperty);
@@ -170,6 +161,7 @@ namespace HandyControl.Controls
TabPanel.FluidMoveDuration = new Duration(TimeSpan.FromSeconds(0));
}
TabControlParent.IsInternalAction = true;
RaiseEvent(new RoutedEventArgs(ClosedEvent, this));
TabControlParent.Items.Remove(this);
}
@@ -178,17 +170,21 @@ namespace HandyControl.Controls
base.OnMouseLeftButtonDown(e);
if (TabControlParent.IsDraggable && !ItemIsDragging && !_isDragging)
{
TabControlParent.UpdateScroll();
TabPanel.FluidMoveDuration = new Duration(TimeSpan.FromSeconds(0));
_mouseDownOffsetX = RenderTransform.Value.OffsetX;
var mx = TranslatePoint(new Point(), TabControlParent).X;
_scrollHorizontalOffset = TabControlParent.GetHorizontalOffset();
var mx = TranslatePoint(new Point(), TabControlParent).X + _scrollHorizontalOffset;
_mouseDownIndex = CalLocationIndex(mx);
_maxMoveLeft = -_mouseDownIndex * ItemWidth;
var subIndex = _mouseDownIndex - CalLocationIndex(_scrollHorizontalOffset);
_maxMoveLeft = -subIndex * ItemWidth;
_maxMoveRight = TabControlParent.ActualWidth - ActualWidth + _maxMoveLeft;
_isDragging = true;
ItemIsDragging = true;
_isWaiting = true;
_dragPoint = e.GetPosition(TabControlParent);
_dragPoint = new Point(_dragPoint.X + +_scrollHorizontalOffset, _dragPoint.Y);
_mouseDownPoint = _dragPoint;
CaptureMouse();
}
@@ -199,9 +195,10 @@ namespace HandyControl.Controls
base.OnMouseMove(e);
if (ItemIsDragging && _isDragging)
{
var subX = TranslatePoint(new Point(), TabControlParent).X;
var subX = TranslatePoint(new Point(), TabControlParent).X + _scrollHorizontalOffset;
CurrentIndex = CalLocationIndex(subX);
var p = e.GetPosition(TabControlParent);
p = new Point(p.X + _scrollHorizontalOffset, p.Y);
var subLeft = p.X - _dragPoint.X;
var totalLeft = p.X - _mouseDownPoint.X;
@@ -229,7 +226,7 @@ namespace HandyControl.Controls
ReleaseMouseCapture();
if (_isDragged)
{
var subX = TranslatePoint(new Point(), TabControlParent).X;
var subX = TranslatePoint(new Point(), TabControlParent).X + _scrollHorizontalOffset;
var index = CalLocationIndex(subX);
var left = index * ItemWidth;
var offsetX = RenderTransform.Value.OffsetX;
@@ -273,7 +270,7 @@ namespace HandyControl.Controls
animation.Completed += (s1, e1) => AnimationCompleted();
var f = new TranslateTransform(offsetX, 0);
RenderTransform = f;
f.BeginAnimation(TranslateTransform.XProperty, animation);
f.BeginAnimation(TranslateTransform.XProperty, animation, HandoffBehavior.Compose);
}
/// <summary>
@@ -290,5 +287,21 @@ namespace HandyControl.Controls
return result > maxIndex ? maxIndex : result;
}
public static readonly RoutedEvent ClosingEvent = EventManager.RegisterRoutedEvent("Closing", RoutingStrategy.Bubble, typeof(EventHandler), typeof(TabItem));
public event EventHandler Closing
{
add => AddHandler(ClosingEvent, value);
remove => RemoveHandler(ClosingEvent, value);
}
public static readonly RoutedEvent ClosedEvent = EventManager.RegisterRoutedEvent("Closed", RoutingStrategy.Bubble, typeof(EventHandler), typeof(TabItem));
public event EventHandler Closed
{
add => AddHandler(ClosedEvent, value);
remove => RemoveHandler(ClosedEvent, value);
}
}
}
@@ -6,26 +6,23 @@ using System.Windows.Controls.Primitives;
using System.Windows.Data;
using System.Windows.Input;
using System.Windows.Media;
using HandyControl.Data;
using HandyControl.Tools;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementButtonAm, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementButtonPm, Type = typeof(RadioButton))]
[TemplatePart(Name = ElementButtonConfirm, Type = typeof(Button))]
[TemplatePart(Name = ElementCanvas, Type = typeof(Canvas))]
[TemplatePart(Name = ElementBorderTitle, Type = typeof(Border))]
[TemplatePart(Name = ElementBorderClock, Type = typeof(Border))]
[TemplatePart(Name = ElementPanelNum, Type = typeof(CirclePanel))]
[TemplatePart(Name = ElementTimeStr, Type = typeof(TextBlock))]
public class Clock : Control
public class Clock : ClockBase
{
#region Constants
private const string ElementButtonAm = "PART_ButtonAm";
private const string ElementButtonPm = "PART_ButtonPm";
private const string ElementButtonConfirm = "PART_ButtonConfirm";
private const string ElementCanvas = "PART_Canvas";
private const string ElementBorderTitle = "PART_BorderTitle";
private const string ElementBorderClock = "PART_BorderClock";
@@ -40,8 +37,6 @@ namespace HandyControl.Controls
private RadioButton _buttonPm;
private Button _buttonConfirm;
private Canvas _canvas;
private Border _borderTitle;
@@ -60,59 +55,10 @@ namespace HandyControl.Controls
private int _secValue;
private bool _appliedTemplate;
#endregion Data
#region Public Events
public static readonly RoutedEvent SelectedTimeChangedEvent =
EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Direct,
typeof(EventHandler<FunctionEventArgs<DateTime?>>), typeof(Clock));
public event EventHandler<FunctionEventArgs<DateTime?>> SelectedTimeChanged
{
add => AddHandler(SelectedTimeChangedEvent, value);
remove => RemoveHandler(SelectedTimeChangedEvent, value);
}
public event EventHandler<FunctionEventArgs<DateTime>> DisplayTimeChanged;
public event Action Confirmed;
#endregion Public Events
#region Public Properties
public static readonly DependencyProperty SelectedTimeProperty = DependencyProperty.Register(
"SelectedTime", typeof(DateTime?), typeof(Clock), new PropertyMetadata(default(DateTime?), OnSelectedTimeChanged));
private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Clock)d;
var v = (DateTime?)e.NewValue;
ctl.DisplayTime = v ?? DateTime.Now;
ctl.OnSelectedTimeChanged(new FunctionEventArgs<DateTime?>(SelectedTimeChangedEvent, ctl)
{
Info = v
});
}
public DateTime? SelectedTime
{
get => (DateTime?) GetValue(SelectedTimeProperty);
set => SetValue(SelectedTimeProperty, value);
}
public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register(
"TimeFormat", typeof(string), typeof(Clock), new PropertyMetadata("HH:mm:ss"));
public string TimeFormat
{
get => (string) GetValue(TimeFormatProperty);
set => SetValue(TimeFormatProperty, value);
}
public static readonly DependencyProperty ClockRadioButtonStyleProperty = DependencyProperty.Register(
"ClockRadioButtonStyle", typeof(Style), typeof(Clock), new PropertyMetadata(default(Style)));
@@ -122,32 +68,6 @@ namespace HandyControl.Controls
set => SetValue(ClockRadioButtonStyleProperty, value);
}
public static readonly DependencyProperty DisplayTimeProperty = DependencyProperty.Register(
"DisplayTime", typeof(DateTime), typeof(Clock), new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnDisplayTimeChanged));
private static void OnDisplayTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (Clock) d;
var v = (DateTime) e.NewValue;
ctl.Update(v);
ctl.OnDisplayTimeChanged(new FunctionEventArgs<DateTime>(v));
}
public DateTime DisplayTime
{
get => (DateTime) GetValue(DisplayTimeProperty);
set => SetValue(DisplayTimeProperty, value);
}
internal static readonly DependencyProperty ShowConfirmButtonProperty = DependencyProperty.Register(
"ShowConfirmButton", typeof(bool), typeof(Clock), new PropertyMetadata(ValueBoxes.FalseBox));
internal bool ShowConfirmButton
{
get => (bool)GetValue(ShowConfirmButtonProperty);
set => SetValue(ShowConfirmButtonProperty, value);
}
private int SecValue
{
get => _secValue;
@@ -174,7 +94,7 @@ namespace HandyControl.Controls
public override void OnApplyTemplate()
{
_appliedTemplate = false;
AppliedTemplate = false;
if (_buttonAm != null)
{
_buttonAm.Click -= ButtonAm_OnClick;
@@ -185,9 +105,9 @@ namespace HandyControl.Controls
_buttonPm.Click -= ButtonPm_OnClick;
}
if (_buttonConfirm != null)
if (ButtonConfirm != null)
{
_buttonConfirm.Click -= ButtonConfirm_OnClick;
ButtonConfirm.Click -= ButtonConfirm_OnClick;
}
if (_borderTitle != null)
@@ -206,18 +126,18 @@ namespace HandyControl.Controls
_buttonAm = GetTemplateChild(ElementButtonAm) as RadioButton;
_buttonPm = GetTemplateChild(ElementButtonPm) as RadioButton;
_buttonConfirm = GetTemplateChild(ElementButtonConfirm) as Button;
ButtonConfirm = GetTemplateChild(ElementButtonConfirm) as Button;
_borderTitle = GetTemplateChild(ElementBorderTitle) as Border;
_canvas = GetTemplateChild(ElementCanvas) as Canvas;
_borderClock = GetTemplateChild(ElementBorderClock) as Border;
_circlePanel = GetTemplateChild(ElementPanelNum) as CirclePanel;
_blockTime = GetTemplateChild(ElementTimeStr) as TextBlock;
CheckNull();
if (!CheckNull()) return;
_buttonAm.Click += ButtonAm_OnClick;
_buttonPm.Click += ButtonPm_OnClick;
_buttonConfirm.Click += ButtonConfirm_OnClick;
ButtonConfirm.Click += ButtonConfirm_OnClick;
_borderTitle.MouseWheel += BorderTitle_OnMouseWheel;
_canvas.MouseWheel += Canvas_OnMouseWheel;
@@ -241,7 +161,7 @@ namespace HandyControl.Controls
_circlePanel.Children.Add(button);
}
_appliedTemplate = true;
AppliedTemplate = true;
if (SelectedTime.HasValue)
{
Update(SelectedTime.Value);
@@ -255,26 +175,15 @@ namespace HandyControl.Controls
#endregion Public Methods
#region Protected Methods
protected virtual void OnSelectedTimeChanged(FunctionEventArgs<DateTime?> e) => RaiseEvent(e);
protected virtual void OnDisplayTimeChanged(FunctionEventArgs<DateTime> e)
{
var handler = DisplayTimeChanged;
handler?.Invoke(this, e);
}
#endregion Protected Methods
#region Private Methods
private void CheckNull()
private bool CheckNull()
{
if (_buttonPm == null || _buttonAm == null || _buttonConfirm == null || _canvas == null ||
if (_buttonPm == null || _buttonAm == null || ButtonConfirm == null || _canvas == null ||
_borderTitle == null || _borderClock == null || _circlePanel == null ||
_blockTime == null) throw new Exception();
_blockTime == null) return false;
return true;
}
private void BorderTitle_OnMouseWheel(object sender, MouseWheelEventArgs e)
@@ -339,7 +248,7 @@ namespace HandyControl.Controls
private void Update()
{
if (!_appliedTemplate) return;
if (!AppliedTemplate) return;
var hValue = _currentButton.Num;
if (_buttonPm.IsChecked == true)
{
@@ -367,9 +276,9 @@ namespace HandyControl.Controls
/// 更新
/// </summary>
/// <param name="time"></param>
internal void Update(DateTime time)
internal override void Update(DateTime time)
{
if (!_appliedTemplate) return;
if (!AppliedTemplate) return;
var h = time.Hour;
var m = time.Minute;
@@ -396,12 +305,6 @@ namespace HandyControl.Controls
Update();
}
private void ButtonConfirm_OnClick(object sender, RoutedEventArgs e)
{
SelectedTime = DisplayTime;
Confirmed?.Invoke();
}
/// <summary>
/// 获取显示时间
/// </summary>
@@ -0,0 +1,106 @@
using System;
using System.Windows;
using System.Windows.Controls;
using HandyControl.Data;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementButtonConfirm, Type = typeof(Button))]
public abstract class ClockBase : Control
{
protected const string ElementButtonConfirm = "PART_ButtonConfirm";
protected Button ButtonConfirm;
protected bool AppliedTemplate;
public event Action Confirmed;
public event EventHandler<FunctionEventArgs<DateTime>> DisplayTimeChanged;
public static readonly RoutedEvent SelectedTimeChangedEvent =
EventManager.RegisterRoutedEvent("SelectedTimeChanged", RoutingStrategy.Direct,
typeof(EventHandler<FunctionEventArgs<DateTime?>>), typeof(ClockBase));
public event EventHandler<FunctionEventArgs<DateTime?>> SelectedTimeChanged
{
add => AddHandler(SelectedTimeChangedEvent, value);
remove => RemoveHandler(SelectedTimeChangedEvent, value);
}
public static readonly DependencyProperty TimeFormatProperty = DependencyProperty.Register(
"TimeFormat", typeof(string), typeof(ClockBase), new PropertyMetadata("HH:mm:ss"));
public string TimeFormat
{
get => (string)GetValue(TimeFormatProperty);
set => SetValue(TimeFormatProperty, value);
}
public static readonly DependencyProperty SelectedTimeProperty = DependencyProperty.Register(
"SelectedTime", typeof(DateTime?), typeof(ClockBase), new PropertyMetadata(default(DateTime?), OnSelectedTimeChanged));
private static void OnSelectedTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (ClockBase)d;
var v = (DateTime?)e.NewValue;
ctl.DisplayTime = v ?? DateTime.Now;
ctl.OnSelectedTimeChanged(new FunctionEventArgs<DateTime?>(SelectedTimeChangedEvent, ctl)
{
Info = v
});
}
public DateTime? SelectedTime
{
get => (DateTime?) GetValue(SelectedTimeProperty);
set => SetValue(SelectedTimeProperty, value);
}
public static readonly DependencyProperty DisplayTimeProperty = DependencyProperty.Register(
"DisplayTime", typeof(DateTime), typeof(ClockBase),
new FrameworkPropertyMetadata(DateTime.Now, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
OnDisplayTimeChanged));
private static void OnDisplayTimeChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var ctl = (ClockBase)d;
var v = (DateTime)e.NewValue;
ctl.Update(v);
ctl.OnDisplayTimeChanged(new FunctionEventArgs<DateTime>(v));
}
public DateTime DisplayTime
{
get => (DateTime)GetValue(DisplayTimeProperty);
set => SetValue(DisplayTimeProperty, value);
}
internal static readonly DependencyProperty ShowConfirmButtonProperty = DependencyProperty.Register(
"ShowConfirmButton", typeof(bool), typeof(ClockBase), new PropertyMetadata(ValueBoxes.FalseBox));
internal bool ShowConfirmButton
{
get => (bool) GetValue(ShowConfirmButtonProperty);
set => SetValue(ShowConfirmButtonProperty, value);
}
protected virtual void OnSelectedTimeChanged(FunctionEventArgs<DateTime?> e) => RaiseEvent(e);
protected virtual void OnDisplayTimeChanged(FunctionEventArgs<DateTime> e)
{
var handler = DisplayTimeChanged;
handler?.Invoke(this, e);
}
protected void ButtonConfirm_OnClick(object sender, RoutedEventArgs e)
{
SelectedTime = DisplayTime;
Confirmed?.Invoke();
}
internal abstract void Update(DateTime time);
protected void Clock_SelectedTimeChanged(object sender, FunctionEventArgs<DateTime?> e) => SelectedTime = e.Info;
}
}
@@ -0,0 +1,148 @@
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace HandyControl.Controls
{
[TemplatePart(Name = ElementHourList, Type = typeof(ListBox))]
[TemplatePart(Name = ElementMinuteList, Type = typeof(ListBox))]
[TemplatePart(Name = ElementSecondList, Type = typeof(ListBox))]
public class ListClock : ClockBase
{
#region Constants
private const string ElementHourList = "PART_HourList";
private const string ElementMinuteList = "PART_MinuteList";
private const string ElementSecondList = "PART_SecondList";
#endregion Constants
#region Data
private ListBox _hourList;
private ListBox _minuteList;
private ListBox _secondList;
#endregion Data
public override void OnApplyTemplate()
{
AppliedTemplate = false;
if (ButtonConfirm != null)
{
ButtonConfirm.Click -= ButtonConfirm_OnClick;
}
if (_hourList != null)
{
_hourList.SelectionChanged -= HourList_SelectionChanged;
}
if (_minuteList != null)
{
_minuteList.SelectionChanged -= MinuteList_SelectionChanged;
}
if (_secondList != null)
{
_secondList.SelectionChanged -= SecondList_SelectionChanged;
}
base.OnApplyTemplate();
_hourList = GetTemplateChild(ElementHourList) as ListBox;
if (_hourList != null)
{
CreateItemsSource(_hourList, 24);
_hourList.SelectionChanged += HourList_SelectionChanged;
}
_minuteList = GetTemplateChild(ElementMinuteList) as ListBox;
if (_minuteList != null)
{
CreateItemsSource(_minuteList, 60);
_minuteList.SelectionChanged += MinuteList_SelectionChanged;
}
_secondList = GetTemplateChild(ElementSecondList) as ListBox;
if (_secondList != null)
{
CreateItemsSource(_secondList, 60);
_secondList.SelectionChanged += SecondList_SelectionChanged;
}
ButtonConfirm = GetTemplateChild(ElementButtonConfirm) as Button;
if (ButtonConfirm != null)
{
ButtonConfirm.Click += ButtonConfirm_OnClick;
}
AppliedTemplate = true;
if (SelectedTime.HasValue)
{
Update(SelectedTime.Value);
}
else
{
DisplayTime = DateTime.Now;
Update(DisplayTime);
}
}
private void HourList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update();
private void MinuteList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update();
private void SecondList_SelectionChanged(object sender, SelectionChangedEventArgs e) => Update();
private void CreateItemsSource(ItemsControl selector, int count)
{
var list = new List<string>();
for (int i = 0; i < count; i++)
{
list.Add(i.ToString("#00"));
}
selector.ItemsSource = list;
}
private void Update()
{
if (_hourList.SelectedIndex >= 0 && _hourList.SelectedIndex < 24 &&
_minuteList.SelectedIndex >= 0 && _minuteList.SelectedIndex < 60 &&
_secondList.SelectedIndex >= 0 && _secondList.SelectedIndex < 60)
{
var now = DateTime.Now;
DisplayTime = new DateTime(now.Year, now.Month, now.Day, _hourList.SelectedIndex,
_minuteList.SelectedIndex, _secondList.SelectedIndex);
}
}
/// <summary>
/// 更新
/// </summary>
/// <param name="time"></param>
internal override void Update(DateTime time)
{
if (!AppliedTemplate) return;
var h = time.Hour;
var m = time.Minute;
var s = time.Second;
_hourList.SelectedIndex = h;
_minuteList.SelectedIndex = m;
_secondList.SelectedIndex = s;
_hourList.ScrollIntoView(_hourList.SelectedItem);
_minuteList.ScrollIntoView(_minuteList.SelectedItem);
_secondList.ScrollIntoView(_secondList.SelectedItem);
DisplayTime = time;
}
}
}
@@ -0,0 +1,12 @@
using System;
using HandyControl.Tools.Interop;
namespace HandyControl.Data
{
internal class MouseHookEventArgs : EventArgs
{
public MouseHookMessageType Message { get; set; }
public NativeMethods.POINT Point { get; set; }
}
}
@@ -0,0 +1,12 @@
namespace HandyControl.Data
{
public enum MouseHookMessageType
{
LeftButtonDown = 0x0201,
LeftButtonUp = 0x0202,
MouseMove = 0x0200,
MouseWheel = 0x020A,
RightButtonDown = 0x0204,
RightButtonUp = 0x0205
}
}
@@ -1,5 +1,6 @@
using System;
using HandyControl.Controls;
using HandyControl.Tools;
namespace HandyControl.Data
{
@@ -35,6 +35,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\ContextMenuButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\ContextMenuToggleButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Button\ProgressButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\ColorPicker\ColorDropper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Cover\CoverFlow\CoverFlow.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Cover\CoverFlow\CoverFlowItem.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Cover\CoverView\CoverView.cs" />
@@ -62,7 +63,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Badge.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Carousel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ChatBubble.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\ColorPicker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\ColorPicker\ColorPicker.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Dialog.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\GotoTop.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Other\Gravatar.cs" />
@@ -95,7 +96,9 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Text\Tag\TagPanel.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\CalendarWithClock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\Clock\Clock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\Clock\ListClock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\Clock\ClockRadioButton.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\Clock\ClockBase.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\FlipClock\FlipClock.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\FlipClock\FlipNumber.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Controls\Time\TimeBar\SpeTextBlock.cs" />
@@ -110,6 +113,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Controls\Window\Window.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Args\CancelRoutedEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Args\FunctionEventArgs!1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Args\MouseHookEventArgs.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\ColorRange.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\BadgeStatus.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\ChatMessageType.cs" />
@@ -133,6 +137,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Data\GrowlInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\HandyControlConfig.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\MessageBoxInfo.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Enum\MouseHookMessageType.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Operation\OperationResult!1.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\Operation\OperationResult.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Data\ResourceToken.cs" />
@@ -241,6 +246,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\SingleOpenHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\ValidateHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Helper\VisualHelper.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Hook\MouseHook.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\BitmapHandle.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\BITMAPINFO.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Tools\Interop\CommonHandles.cs" />
Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

@@ -38,5 +38,6 @@
<Geometry x:Key="AskGeometry">M512 0 30.11843 240.941297l0 542.117406 481.88157 240.941297 481.88157-240.941297L993.88157 240.941297 512 0zM575.776472 768.799969 460.188012 768.799969 460.188012 656.222073l115.588459 0L575.776472 768.799969zM623.335603 509.329685c-52.375829 36.723353-59.600363 55.988096-59.600363 84.885211l0 19.866447L468.616977 614.081343l0-26.489278c0-45.754021 13.846342-80.67124 61.406497-116.791866 46.957428-36.723353 57.79423-62.0082 57.79423-84.282484 0-25.284848-21.67258-54.181962-55.386393-54.181962-42.743457 0-70.436142 26.489278-82.477374 85.486914l-105.956088-21.67258c24.683144-111.976192 82.477374-157.127486 205.289345-157.127486 98.12985 0 157.72919 63.212631 157.72919 131.842639C707.017407 423.240044 688.956071 461.76953 623.335603 509.329685z</Geometry>
<Geometry x:Key="AllGeometry">M 721.005 638.949 C 758.74 638.949 789.333 669.56 789.333 707.312 C 789.333 745.047 758.74 775.657 721.005 775.657 C 683.253 775.657 652.66 745.047 652.66 707.312 C 652.66 669.56 683.253 638.949 721.005 638.949 Z M 512.017 638.949 C 549.77 638.949 580.38 669.56 580.38 707.312 C 580.38 745.047 549.77 775.657 512.017 775.657 C 474.265 775.657 443.672 745.047 443.672 707.312 C 443.672 669.56 474.265 638.949 512.017 638.949 Z M 303.029 638.949 C 340.781 638.949 371.392 669.56 371.392 707.312 C 371.392 745.047 340.781 775.657 303.029 775.657 C 265.277 775.657 234.667 745.047 234.667 707.312 C 234.667 669.56 265.277 638.949 303.029 638.949 Z M 721.005 443.655 C 758.74 443.655 789.333 474.265 789.333 512.017 C 789.333 549.769 758.74 580.363 721.005 580.363 C 683.253 580.363 652.66 549.769 652.66 512.017 C 652.66 474.265 683.253 443.655 721.005 443.655 Z M 512.017 443.655 C 549.77 443.655 580.38 474.265 580.38 512.017 C 580.38 549.769 549.77 580.363 512.017 580.363 C 474.265 580.363 443.672 549.769 443.672 512.017 C 443.672 474.265 474.265 443.655 512.017 443.655 Z M 303.029 443.655 C 340.781 443.655 371.392 474.265 371.392 512.017 C 371.392 549.769 340.781 580.363 303.029 580.363 C 265.277 580.363 234.667 549.769 234.667 512.017 C 234.667 474.265 265.277 443.655 303.029 443.655 Z M 721.005 248.343 C 758.74 248.343 789.333 278.953 789.333 316.688 C 789.333 354.44 758.74 385.051 721.005 385.051 C 683.253 385.051 652.66 354.44 652.66 316.688 C 652.66 278.953 683.253 248.343 721.005 248.343 Z M 512.017 248.343 C 549.77 248.343 580.38 278.953 580.38 316.688 C 580.38 354.44 549.77 385.051 512.017 385.051 C 474.265 385.051 443.672 354.44 443.672 316.688 C 443.672 278.953 474.265 248.343 512.017 248.343 Z M 303.029 248.343 C 340.781 248.343 371.392 278.953 371.392 316.688 C 371.392 354.44 340.781 385.051 303.029 385.051 C 265.277 385.051 234.667 354.44 234.667 316.688 C 234.667 278.953 265.277 248.343 303.029 248.343 Z</Geometry>
<Geometry x:Key="DragGeometry">M384 896C384 825.307552 440.814697 768 512 768 582.692448 768 640 824.814694 640 896 640 966.692448 583.185303 1024 512 1024 441.307552 1024 384 967.185306 384 896ZM384 512C384 441.307552 440.814697 384 512 384 582.692448 384 640 440.814697 640 512 640 582.692448 583.185303 640 512 640 441.307552 640 384 583.185303 384 512ZM384 128C384 57.307552 440.814697 0 512 0 582.692448 0 640 56.814697 640 128 640 198.692448 583.185303 256 512 256 441.307552 256 384 199.185303 384 128Z</Geometry>
<Geometry x:Key="DropperGeometry">M798.165333 97.834667a42.624 42.624 0 0 0-60.330666 0l-140.629334 140.629333-55.381333-55.296-60.330667 60.330667 55.381334 55.296-353.706667 353.706666a42.709333 42.709333 0 0 0-11.221333 19.84l-42.666667 170.666667a42.538667 42.538667 0 0 0 51.712 51.712l170.666667-42.666667c7.509333-1.877333 14.378667-5.76 19.84-11.221333l353.792-353.792 55.210666 55.125333 60.330667-60.330666-55.210667-55.125334 140.544-140.544a42.624 42.624 0 0 0 0-60.330666l-128-128zM319.488 772.138667l-90.197333 22.570666 22.570666-90.197333 345.386667-345.386667 67.669333 67.584-345.429333 345.429334z</Geometry>
</ResourceDictionary>
@@ -9,7 +9,7 @@
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Viewport3D x:Name="PART_Viewport3D">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="PART_Camera" Position="0,0,3" UpDirection="0,1,0" LookDirection="0,0,-1" FieldOfView="100" NearPlaneDistance="0.125"/>
<PerspectiveCamera x:Name="PART_Camera" Position="0,0,3" UpDirection="0,1,0" LookDirection="0,0,-1" FieldOfView="90"/>
</Viewport3D.Camera>
<Viewport3D.Children>
<ModelVisual3D>
@@ -50,7 +50,7 @@
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="controls:StatusSwitchElement.HiddenElement" Value="True"/>
<Condition Property="controls:StatusSwitchElement.HideUncheckedElement" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed" TargetName="UnCheckedElement"/>
@@ -6,6 +6,7 @@
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="../Basic/Converters.xaml"/>
<ResourceDictionary Source="Button.xaml"/>
<ResourceDictionary Source="Base/ListBoxBaseStyle.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style x:Key="ClockRadioButtonStyle" TargetType="controls:ClockRadioButton">
@@ -94,7 +95,7 @@
</Canvas>
<controls:ClockRadioButton Background="{DynamicResource PrimaryBrush}" Grid.Column="0" x:Name="PART_ButtonAm" IsChecked="True" Height="30" Width="30" HorizontalAlignment="Left" VerticalAlignment="Bottom" Margin="16,0,0,16" Content="{x:Static langs:Lang.Am}" Style="{StaticResource ClockRadioButtonStyle}"/>
<controls:ClockRadioButton Background="{DynamicResource PrimaryBrush}" Grid.Column="2" x:Name="PART_ButtonPm" Height="30" Width="30" HorizontalAlignment="Right" VerticalAlignment="Bottom" Margin="0,0,16,16" Content="{x:Static langs:Lang.Pm}" Style="{StaticResource ClockRadioButtonStyle}"/>
<Button Grid.Column="1" Visibility="{TemplateBinding ShowConfirmButton,Converter={StaticResource Boolean2VisibilityConverter}}" Name="PART_ButtonConfirm" Content="{x:Static langs:Lang.Confirm}" Foreground="{DynamicResource PrimaryBrush}" HorizontalAlignment="Center" Margin="0,0,0,19" Height="24" Width="60" VerticalAlignment="Bottom" Background="Transparent" Style="{StaticResource ButtonCustom}"/>
<Button Grid.Column="1" Visibility="{TemplateBinding ShowConfirmButton,Converter={StaticResource Boolean2VisibilityConverter}}" Name="PART_ButtonConfirm" Content="{x:Static langs:Lang.Confirm}" Foreground="{DynamicResource PrimaryBrush}" HorizontalAlignment="Center" Margin="0,0,0,19" Height="24" Width="60" VerticalAlignment="Bottom" Background="Transparent" Style="{StaticResource ButtonCustom}"/>
</Grid>
</Border>
</Grid>
@@ -103,5 +104,76 @@
</Setter.Value>
</Setter>
</Style>
<Style x:Key="ClockListBoxItemStyle" TargetType="ListBoxItem" BasedOn="{StaticResource ListBoxItemBaseStyle}">
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background" Value="{DynamicResource SecondaryRegionBrush}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background" Value="{DynamicResource PrimaryBrush}"/>
<Setter Property="Foreground" Value="{DynamicResource TextIconBrush}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" Value=".4"/>
</Trigger>
<Trigger Property="controls:EdgeElement.ShowEdgeContent" Value="true">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
<StackPanel Orientation="Horizontal">
<ContentControl Width="16" Height="16" Content="{Binding Path=(controls:EdgeElement.LeftContent),RelativeSource={RelativeSource TemplatedParent}}"/>
<ContentPresenter Margin="6,0,0,0" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</StackPanel>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="ClockListBoxStyle" TargetType="ListBox" BasedOn="{StaticResource ListBoxBaseStyle}">
<Setter Property="MaxHeight" Value="192"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="ItemContainerStyle" Value="{StaticResource ClockListBoxItemStyle}"/>
</Style>
<Style TargetType="controls:ListClock">
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}"/>
<Setter Property="Width" Value="210"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
<Setter Property="controls:TitleElement.Background" Value="{DynamicResource TitleBrush}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:ListClock">
<Border BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox x:Name="PART_HourList" Style="{StaticResource ClockListBoxStyle}"/>
<ListBox Grid.Row="0" Grid.Column="1" x:Name="PART_MinuteList" Style="{StaticResource ClockListBoxStyle}" BorderThickness="1,0"/>
<ListBox Grid.Row="0" Grid.Column="2" x:Name="PART_SecondList" Style="{StaticResource ClockListBoxStyle}"/>
<Border VerticalAlignment="Bottom" Visibility="{Binding Visibility,ElementName=PART_ButtonConfirm}" Height="1" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3" Background="{DynamicResource BorderBrush}"/>
<Button Margin="0,10" Grid.Column="0" Grid.ColumnSpan="3" Grid.Row="1" Visibility="{TemplateBinding ShowConfirmButton,Converter={StaticResource Boolean2VisibilityConverter}}" Name="PART_ButtonConfirm" Content="{x:Static langs:Lang.Confirm}" Foreground="{DynamicResource PrimaryBrush}" HorizontalAlignment="Center" Background="Transparent" Style="{StaticResource ButtonCustom}"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
@@ -9,6 +9,7 @@
<ResourceDictionary Source="../Basic/Converters.xaml"/>
<ResourceDictionary Source="Slider.xaml"/>
<ResourceDictionary Source="Button.xaml"/>
<ResourceDictionary Source="ToggleButton.xaml"/>
</ResourceDictionary.MergedDictionaries>
<Style TargetType="controls:ColorPicker">
@@ -63,19 +64,26 @@
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="28"/>
</Grid.ColumnDefinitions>
<Border Width="60" Height="32" CornerRadius="2" Background="{StaticResource ColorPickerOpacityBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"/>
<Border Grid.Row="0" Grid.Column="0" Width="60" Height="32" CornerRadius="2" Background="{TemplateBinding SelectedBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"/>
<Slider Name="PART_SliderColor" LargeChange="0.01" SmallChange="0.01" Grid.ColumnSpan="2" Value="6" Maximum="6" Background="{StaticResource ColorPickerRainbowBrush}" Margin="10,1,0,0" Grid.Row="0" Grid.Column="1" VerticalAlignment="Top" Style="{StaticResource ColorPickerSlider}" IsMoveToPointEnabled="True"/>
<Slider Name="PART_SliderOpacity" Grid.ColumnSpan="2" IsSnapToTickEnabled="True" Value="{Binding ChannelA,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" Maximum="255" SmallChange="1" Foreground="{TemplateBinding SelectedBrushWithoutOpacity}" Background="{StaticResource ColorPickerOpacityBrush}" Margin="10,0,0,0" Grid.Row="0" Grid.Column="1" VerticalAlignment="Bottom" Style="{StaticResource ColorPickerSlider}" IsMoveToPointEnabled="True"/>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="0,14,0,0" VerticalAlignment="Top" Visibility="{Binding ShowList[0],RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}">
<ToggleButton Name="PART_ButtonDropper" Width="16" Height="16" Margin="0,0,10,0" Style="{StaticResource ToggleButtonCustom}" controls:StatusSwitchElement.HideUncheckedElement="True">
<Path Data="{StaticResource DropperGeometry}" Fill="{DynamicResource PrimaryTextBrush}"/>
<controls:StatusSwitchElement.CheckedElement>
<Path Data="{StaticResource DropperGeometry}" Fill="{DynamicResource DarkPrimaryBrush}"/>
</controls:StatusSwitchElement.CheckedElement>
</ToggleButton>
<Border Grid.Row="0" Grid.Column="1" Width="32" Height="32" CornerRadius="16" Background="{StaticResource ColorPickerOpacityBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"/>
<Border Grid.Row="0" Grid.Column="1" Width="32" Height="32" CornerRadius="16" Background="{TemplateBinding SelectedBrush}" BorderBrush="{DynamicResource BorderBrush}" BorderThickness="1"/>
<Slider Name="PART_SliderColor" LargeChange="0.01" SmallChange="0.01" Grid.ColumnSpan="2" Value="6" Maximum="6" Background="{StaticResource ColorPickerRainbowBrush}" Margin="2,1,0,0" Grid.Row="0" Grid.Column="2" VerticalAlignment="Top" Style="{StaticResource ColorPickerSlider}" IsMoveToPointEnabled="True"/>
<Slider Name="PART_SliderOpacity" Grid.ColumnSpan="2" IsSnapToTickEnabled="True" Value="{Binding ChannelA,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" Maximum="255" SmallChange="1" Foreground="{TemplateBinding SelectedBrushWithoutOpacity}" Background="{StaticResource ColorPickerOpacityBrush}" Margin="2,0,0,0" Grid.Row="0" Grid.Column="2" VerticalAlignment="Bottom" Style="{StaticResource ColorPickerSlider}" IsMoveToPointEnabled="True"/>
<StackPanel Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="0,14,0,0" VerticalAlignment="Top" Visibility="{Binding ShowList[0],RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}">
<TextBox Padding="0" HorizontalContentAlignment="Center" Width="176" Text="{Binding SelectedBrush,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay,Converter={StaticResource Color2HexStrConverter},UpdateSourceTrigger=LostFocus}" FontSize="10" MaxLength="10" Height="24" />
<TextBlock Foreground="{DynamicResource ThirdlyTextBrush}" Margin="0,6,0,0" FontSize="10" Text="HEX" HorizontalAlignment="Center"/>
</StackPanel>
<UniformGrid Name="PART_PanelRgb" Visibility="{Binding ShowList[1],RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}" Rows="1" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2" Margin="-2,14,-2,0" VerticalAlignment="Top">
<UniformGrid Name="PART_PanelRgb" Visibility="{Binding ShowList[1],RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource Boolean2VisibilityConverter}}" Rows="1" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" Margin="-2,14,-2,0" VerticalAlignment="Top">
<StackPanel Margin="2,0">
<controls:NumericUpDown HorizontalContentAlignment="Center" Padding="2,0" Tag="R" Value="{Binding ChannelR,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}" ShowUpDownButton="False" Maximum="255" Minimum="0" FontSize="10" Height="24" />
<TextBlock Foreground="{DynamicResource ThirdlyTextBrush}" Margin="0,6,0,0" FontSize="10" Text="R" HorizontalAlignment="Center"/>
@@ -93,7 +101,7 @@
<TextBlock Foreground="{DynamicResource ThirdlyTextBrush}" Margin="0,6,0,0" FontSize="10" Text="A" HorizontalAlignment="Center"/>
</StackPanel>
</UniformGrid>
<Button Command="interactivity:ControlCommands.Switch" Padding="6" FontSize="8" BorderThickness="0" HorizontalAlignment="Right" Height="24" Width="20" Grid.Column="2" Grid.Row="1">
<Button Command="interactivity:ControlCommands.Switch" Padding="6" FontSize="8" BorderThickness="0" HorizontalAlignment="Right" Height="24" Width="20" Grid.Column="3" Grid.Row="1">
<Button.Content>
<Path Fill="#323534" Style="{StaticResource UpDownPathStyle}"/>
</Button.Content>
@@ -71,6 +71,86 @@
</Setter>
</Style>
<ControlTemplate x:Key="TabControlPlusTemplate" TargetType="controls:TabControl">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Background="{TemplateBinding Background}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource BorderBrush}">
<controls:TabPanel MinHeight="{TemplateBinding TabItemHeight}" TabItemHeight="{TemplateBinding TabItemHeight}" TabItemWidth="{TemplateBinding TabItemWidth}" IsEnableTabFill="{TemplateBinding IsEnableTabFill}" Margin="0,0,-1,-1" x:Name="PART_HeaderPanel" HorizontalAlignment="Left" Background="{DynamicResource SecondaryTextBrush}" IsItemsHost="true" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1">
<interactivity:Interaction.Behaviors>
<interactivity:FluidMoveBehavior AppliesTo="Children" Duration="{Binding FluidMoveDuration,ElementName=PART_HeaderPanel}">
<interactivity:FluidMoveBehavior.EaseX>
<CubicEase EasingMode="EaseOut"/>
</interactivity:FluidMoveBehavior.EaseX>
</interactivity:FluidMoveBehavior>
</interactivity:Interaction.Behaviors>
</controls:TabPanel>
</Border>
<Border x:Name="contentPanel" Background="{DynamicResource SecondaryRegionBrush}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Border Visibility="{Binding Visibility,ElementName=PART_OverflowButton}" Margin="0,-1,0,0" Grid.Row="0" Grid.Column="0" BorderThickness="1,0,0,1" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}" HorizontalAlignment="Right">
<controls:ContextMenuToggleButton x:Name="PART_OverflowButton" Visibility="Collapsed" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.Geometry="{StaticResource DownGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource UpGeometry}"/>
</Border>
</Grid>
</Border>
</ControlTemplate>
<ControlTemplate x:Key="TabControlPlusScrollableTemplate" TargetType="controls:TabControl">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Border Visibility="{TemplateBinding ShowScrollButton,Converter={StaticResource Boolean2VisibilityConverter}}" Margin="0,-1,0,0" Grid.Row="0" Grid.Column="0" BorderThickness="0,0,1,1" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}" HorizontalAlignment="Left" Panel.ZIndex="2">
<Border.CacheMode>
<BitmapCache SnapsToDevicePixels="True"/>
</Border.CacheMode>
<Button Style="{StaticResource ButtonIcon}" Padding="8" controls:IconElement.Geometry="{StaticResource LeftGeometry}" Foreground="{DynamicResource PrimaryTextBrush}" Background="{DynamicResource SecondaryRegionBrush}" x:Name="PART_ScrollButtonLeft"/>
</Border>
<controls:ScrollViewer HorizontalScrollBarVisibility="Hidden" CanMouseWheel="True" Orientation="Horizontal" IsEnableInertia="True" Grid.Row="0" Grid.Column="1" IsDeferredScrollingEnabled="True" x:Name="PART_OverflowScrollviewer">
<Border Background="{TemplateBinding Background}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource BorderBrush}" >
<controls:TabPanel MinHeight="{TemplateBinding TabItemHeight}" TabItemHeight="{TemplateBinding TabItemHeight}" TabItemWidth="{TemplateBinding TabItemWidth}" IsEnableTabFill="{TemplateBinding IsEnableTabFill}" Margin="0,0,-1,-1" x:Name="PART_HeaderPanel" HorizontalAlignment="Left" Background="{DynamicResource SecondaryTextBrush}" IsItemsHost="true" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1">
<interactivity:Interaction.Behaviors>
<interactivity:FluidMoveBehavior AppliesTo="Children" Duration="{Binding FluidMoveDuration,ElementName=PART_HeaderPanel}">
<interactivity:FluidMoveBehavior.EaseX>
<CubicEase EasingMode="EaseOut"/>
</interactivity:FluidMoveBehavior.EaseX>
</interactivity:FluidMoveBehavior>
</interactivity:Interaction.Behaviors>
</controls:TabPanel>
</Border>
</controls:ScrollViewer>
<Border Margin="0,-1,0,0" Grid.Row="0" Grid.Column="2" BorderThickness="1,0,0,1" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}" HorizontalAlignment="Right">
<Border.CacheMode>
<BitmapCache SnapsToDevicePixels="True"/>
</Border.CacheMode>
<StackPanel Orientation="Horizontal">
<Button Visibility="{TemplateBinding ShowScrollButton,Converter={StaticResource Boolean2VisibilityConverter}}" Style="{StaticResource ButtonIcon}" BorderBrush="{DynamicResource BorderBrush}" Padding="8" controls:IconElement.Geometry="{StaticResource RightGeometry}" Foreground="{DynamicResource PrimaryTextBrush}" Background="{DynamicResource SecondaryRegionBrush}" x:Name="PART_ScrollButtonRight"/>
<Border Visibility="{Binding Visibility,ElementName=PART_OverflowButton}" Width="1" Background="{DynamicResource BorderBrush}"/>
<controls:ContextMenuToggleButton x:Name="PART_OverflowButton" Visibility="Collapsed" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.Geometry="{StaticResource DownGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource UpGeometry}"/>
</StackPanel>
</Border>
<Border x:Name="contentPanel" Background="{DynamicResource SecondaryRegionBrush}" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
</Border>
</ControlTemplate>
<Style TargetType="controls:TabControl">
<Setter Property="Padding" Value="0"/>
<Setter Property="Background" Value="{DynamicResource RegionBrush}"/>
@@ -78,41 +158,16 @@
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="controls:TabControl">
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}">
<Grid x:Name="templateRoot" ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<Border Background="{TemplateBinding Background}" BorderThickness="0,0,0,1" BorderBrush="{DynamicResource BorderBrush}">
<controls:TabPanel MinHeight="{TemplateBinding TabItemHeight}" TabItemHeight="{TemplateBinding TabItemHeight}" TabItemWidth="{TemplateBinding TabItemWidth}" IsEnableTabFill="{TemplateBinding IsEnableTabFill}" Margin="0,0,-1,-1" x:Name="PART_HeaderPanel" HorizontalAlignment="Left" Background="{DynamicResource SecondaryTextBrush}" IsItemsHost="true" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1">
<interactivity:Interaction.Behaviors>
<interactivity:FluidMoveBehavior AppliesTo="Children" Duration="{Binding FluidMoveDuration,ElementName=PART_HeaderPanel}">
<interactivity:FluidMoveBehavior.EaseX>
<CubicEase EasingMode="EaseOut"/>
</interactivity:FluidMoveBehavior.EaseX>
</interactivity:FluidMoveBehavior>
</interactivity:Interaction.Behaviors>
</controls:TabPanel>
</Border>
<Border x:Name="contentPanel" Background="{DynamicResource SecondaryRegionBrush}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
<Border Visibility="{Binding Visibility,ElementName=PART_OverflowButton}" Margin="0,-1,0,0" Grid.Row="0" Grid.Column="0" BorderThickness="1,0,0,1" BorderBrush="{DynamicResource BorderBrush}" Background="{DynamicResource RegionBrush}" HorizontalAlignment="Right">
<controls:ContextMenuToggleButton x:Name="PART_OverflowButton" Visibility="Collapsed" Style="{StaticResource ToggleButtonIconTransparent}" controls:IconSwitchElement.Geometry="{StaticResource DownGeometry}" controls:IconSwitchElement.GeometrySelected="{StaticResource UpGeometry}"/>
</Border>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Template" Value="{StaticResource TabControlPlusTemplate}"/>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsScrollable" Value="True"/>
<Condition Property="IsEnableTabFill" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Template" Value="{StaticResource TabControlPlusScrollableTemplate}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style BasedOn="{StaticResource TabControlBaseStyle}" TargetType="TabControl"/>
@@ -135,7 +135,7 @@
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="controls:StatusSwitchElement.HiddenElement" Value="True"/>
<Condition Property="controls:StatusSwitchElement.HideUncheckedElement" Value="True"/>
<Condition Property="IsChecked" Value="True"/>
</MultiTrigger.Conditions>
<Setter Property="Visibility" Value="Collapsed" TargetName="UnCheckedElement"/>
@@ -4,8 +4,9 @@ using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Threading;
using HandyControl.Controls;
using HandyControl.Data;
namespace HandyControl.Data
namespace HandyControl.Tools
{
internal class ImageAnimator
{
@@ -29,7 +29,7 @@
}
/// <summary>
/// 是否在正浮点数范围内
/// 是否在负浮点数范围内
/// </summary>
/// <param name="value"></param>
/// <param name="includeZero"></param>
@@ -0,0 +1,48 @@
using System;
using System.Diagnostics;
using System.Runtime.InteropServices;
using HandyControl.Data;
using HandyControl.Tools.Interop;
namespace HandyControl.Tools
{
internal class MouseHook
{
public static event EventHandler<MouseHookEventArgs> StatusChanged;
private static IntPtr HookId = IntPtr.Zero;
private static readonly UnsafeNativeMethods.HookProc Proc = HookCallback;
public static void Start() => HookId = SetHook(Proc);
public static void Stop() => UnsafeNativeMethods.UnhookWindowsHookEx(HookId);
private static IntPtr SetHook(UnsafeNativeMethods.HookProc proc)
{
using (var curProcess = Process.GetCurrentProcess())
using (var curModule = curProcess.MainModule)
{
if (curModule != null)
{
return UnsafeNativeMethods.SetWindowsHookEx((int) UnsafeNativeMethods.HookType.WH_MOUSE_LL, proc,
UnsafeNativeMethods.GetModuleHandle(curModule.ModuleName), 0);
}
return IntPtr.Zero;
}
}
private static IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
{
if (nCode < 0) return UnsafeNativeMethods.CallNextHookEx(HookId, nCode, wParam, lParam);
var hookStruct = (UnsafeNativeMethods.MOUSEHOOKSTRUCT)Marshal.PtrToStructure(lParam, typeof(UnsafeNativeMethods.MOUSEHOOKSTRUCT));
StatusChanged?.Invoke(null, new MouseHookEventArgs
{
Message = (MouseHookMessageType)wParam,
Point = new NativeMethods.POINT(hookStruct.pt.X, hookStruct.pt.Y)
});
return UnsafeNativeMethods.CallNextHookEx(HookId, nCode, wParam, lParam);
}
}
}
@@ -174,5 +174,45 @@ namespace HandyControl.Tools.Interop
[DllImport(ExternDll.User32, ExactSpelling = true, CharSet = CharSet.Auto)]
public static extern bool SetForegroundWindow(IntPtr hWnd);
[DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CallNextHookEx(IntPtr hhk, int nCode, IntPtr wParam, IntPtr lParam);
[DllImport(ExternDll.Kernel32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr GetModuleHandle(string lpModuleName);
[DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern bool UnhookWindowsHookEx(IntPtr hhk);
public enum HookType
{
WH_MOUSE_LL = 14,
}
[StructLayout(LayoutKind.Sequential)]
public struct MOUSEHOOKSTRUCT
{
public NativeMethods.POINT pt;
public IntPtr hwnd;
public uint wHitTestCode;
public IntPtr dwExtraInfo;
}
public delegate IntPtr HookProc(int code, IntPtr wParam, IntPtr lParam);
[DllImport(ExternDll.User32, CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr SetWindowsHookEx(int idHook, HookProc lpfn, IntPtr hMod, uint dwThreadId);
[DllImport(ExternDll.User32, SetLastError = true)]
public static extern IntPtr GetDesktopWindow();
[DllImport(ExternDll.User32, SetLastError = true)]
public static extern IntPtr GetWindowDC(IntPtr window);
[DllImport(ExternDll.Gdi32, SetLastError = true)]
public static extern uint GetPixel(IntPtr dc, int x, int y);
[DllImport(ExternDll.User32, SetLastError = true)]
public static extern int ReleaseDC(IntPtr window, IntPtr dc);
}
}