提交 f3dda801 编写于 作者: 柯勇

新增Cascader级联下拉

上级 3658b5de
......@@ -8,7 +8,7 @@
xmlns:assist="clr-namespace:SmartUI.Assist;assembly=SmartUI"
mc:Ignorable="d" Style="{StaticResource DefaultWindowStyle}"
Title="SmartUI" Height="500" Width="1000" WindowStartupLocation="CenterScreen">
<TabControl IsTabStop="False" Margin="0">
<TabControl IsTabStop="False" Margin="0" SelectedIndex="2">
<TabItem Header="Button">
<UniformGrid Columns="7" Rows="6">
<Label Content="默认样式"/>
......@@ -124,12 +124,15 @@
<WrapPanel Orientation="Horizontal" Height="50">
<Label Content="Select选择器"/>
<smart:ComboBoxControl Height="35" Width="200">
<ComboBoxItem>选项一</ComboBoxItem>
<ComboBoxItem>选项二</ComboBoxItem>
<ComboBoxItem>选项三</ComboBoxItem>
<ComboBoxItem>选项四</ComboBoxItem>
<ComboBoxItem>选项五</ComboBoxItem>
<ComboBoxItem Content="选项一"/>
<ComboBoxItem Content="选项二"/>
<ComboBoxItem Content="选项三"/>
<ComboBoxItem Content="选项四"/>
<ComboBoxItem Content="选项五"/>
</smart:ComboBoxControl>
<smart:Cascader ItemsSource="{Binding CascaderItemSource}">
</smart:Cascader>
</WrapPanel>
<WrapPanel Orientation="Horizontal" Height="50">
<Label Content="Switch 开关"/>
......
using SmartUI.Common.Enum;
using SmartUI.Base;
using SmartUI.Common.Enum;
using SmartUI.Demo.Common;
using System;
using System.Collections.Generic;
......@@ -42,14 +43,14 @@ namespace SmartUI.Demo
public MainWindowModel()
{
_iconsArray = (PackIconKind[]) Enum.GetValues(typeof(PackIconKind));
Icons = new ObservableCollection<PackIconKind>(_iconsArray.Take(_iconsPageIndex* _pageSize));
_iconsArray = (PackIconKind[])Enum.GetValues(typeof(PackIconKind));
Icons = new ObservableCollection<PackIconKind>(_iconsArray.Take(_iconsPageIndex * _pageSize));
LoadMoreIconCommand = new RelayCommand(new Action<object>(LoadMoreIcon));
}
private void LoadMoreIcon(object obj)
{
_iconsArray.Skip((_iconsPageIndex - 1) * _pageSize).Take(_pageSize).ToList().ForEach(p => {Icons.Add(p); });
_iconsArray.Skip((_iconsPageIndex - 1) * _pageSize).Take(_pageSize).ToList().ForEach(p => { Icons.Add(p); });
}
......@@ -63,5 +64,41 @@ namespace SmartUI.Demo
}
}
public event PropertyChangedEventHandler PropertyChanged;
public ObservableCollection<CascaderItem> CascaderItemSource { get; set; } = new ObservableCollection<CascaderItem>()
{
new CascaderItem()
{
DisplayName="选项一",Children=new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子项一",Children=new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子子项一"} ,
new CascaderItem(){DisplayName="子子项二"} ,
new CascaderItem(){DisplayName="子子项三"} ,
new CascaderItem(){DisplayName="子子项四"} ,
new CascaderItem(){DisplayName="子子项五"} }
},
new CascaderItem()
{
DisplayName = "子项二",Children = new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子子项一"},
new CascaderItem()
{
DisplayName = "子项三",Children = new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子子项一"} }}
}
}
},
},
new CascaderItem()
{
DisplayName = "选项二",
Children = new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子项二",Children=new ObservableCollection<CascaderItem>(){
new CascaderItem(){DisplayName="子子项二"} }
} }
}
};
}
}
......@@ -43,7 +43,7 @@ namespace SmartUI.Assist
ButtonBase currentItem = default;
if (item is RadioButton itemRadio && itemRadio.GroupName.Equals(groupName))
{
currentItem = preButton;
currentItem = itemRadio;
}
else if (item is CheckBox check)
{
......@@ -70,7 +70,7 @@ namespace SmartUI.Assist
if (border != null)
{
border.CornerRadius = new CornerRadius(0, 4, 4, 0);
border.BorderThickness = new Thickness(0, 1, 1, 1);
border.BorderThickness = new Thickness(1, 1, 1, 1);
}
}
}
......
using SmartUI.Base;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace SmartUI.Controls
{
public class Cascader : ComboBox
{
private const string ITEMSPANEL = "Pack_items";
private StackPanel _itemsPanle;
private Border _border;
public new ObservableCollection<CascaderItem> ItemsSource
{
get { return (ObservableCollection<CascaderItem>)GetValue(ItemsSourceProperty); }
set { SetValue(ItemsSourceProperty, value); }
}
public static new readonly DependencyProperty ItemsSourceProperty =
DependencyProperty.Register(nameof(ItemsSource), typeof(ObservableCollection<CascaderItem>), typeof(Cascader), new PropertyMetadata(default, ItemSourceChanged));
private static void ItemSourceChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (!(d is Cascader cascader && e.NewValue is ObservableCollection<CascaderItem> source))
{
return;
}
cascader.RaiseItems(source);
}
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
base.OnSelectionChanged(e);
IsDropDownOpen = true;
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
_itemsPanle = GetTemplateChild(ITEMSPANEL) as StackPanel;
if (_itemsPanle != null)
RaiseItems(ItemsSource);
_border = GetTemplateChild("border") as Border;
_border.MouseLeftButtonDown += Border_MouseLeftButtonDown;
}
private void RaiseItems(ObservableCollection<CascaderItem> source)
{
if (_itemsPanle is null || source is null || source.Count == 0)
return;
ListBox control = new ListBox() { ItemsSource = source };
control.SelectionChanged += Control_SelectionChanged;
_itemsPanle.Children.Add(control);
}
private void Control_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender is ListBox list)
{
if (e.RemovedItems.Count > 0)
(e.RemovedItems[0] as CascaderItem).IsChecked = false;
int index = _itemsPanle.Children.IndexOf(list);
if (e.AddedItems.Count == 0)
return;
CascaderItem model = e.AddedItems[0] as CascaderItem;
model.IsChecked = true;
if (model.Children is null || model.Children.Count == 0)
{
IsDropDownOpen = false;
if (index + 1 < _itemsPanle.Children.Count)
_itemsPanle.Children.RemoveRange(index + 1, _itemsPanle.Children.Count - index - 1);
this.Text = GetParentNames(model);
this.SelectedItem = model.Data;
return;
}
IsDropDownOpen = true;
foreach (var item in model.Children)
{
item.ParentTree = model;
}
if (_itemsPanle.Children.Count == index + 1)
{
RaiseItems(model.Children);
}
else if (_itemsPanle.Children.Count - 1 > index)
{
(_itemsPanle.Children[index + 1] as ListBox).ItemsSource = model.Children;
if (index + 2 < _itemsPanle.Children.Count)
_itemsPanle.Children.RemoveRange(index + 2, _itemsPanle.Children.Count - index - 2);
}
if (_itemsPanle.Children.Count > 0)
(_itemsPanle.Children[_itemsPanle.Children.Count - 1] as ListBox).BorderThickness = new Thickness(0);
if (_itemsPanle.Children.Count > 1)
(_itemsPanle.Children[_itemsPanle.Children.Count - 2] as ListBox).BorderThickness = new Thickness(0, 0, 1, 0);
}
}
private void Border_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
IsDropDownOpen = !IsDropDownOpen;
}
private string GetParentNames(CascaderItem model)
{
if (model is null)
return string.Empty;
string text = model.DisplayName;
CascaderItem tree = model;
do
{
tree = tree.ParentTree;
text = tree.DisplayName + "/" + text;
} while (tree.ParentTree != null);
return text;
}
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace SmartUI.Base
{
public class CascaderItem : ContentControl
{
public string DisplayName
{
get { return (string)GetValue(DisplayNameProperty); }
set { SetValue(DisplayNameProperty, value); }
}
public static readonly DependencyProperty DisplayNameProperty =
DependencyProperty.Register(nameof(DisplayName), typeof(string), typeof(CascaderItem));
public object Data
{
get { return (object)GetValue(DataProperty); }
set { SetValue(DataProperty, value); }
}
public static readonly DependencyProperty DataProperty =
DependencyProperty.Register(nameof(Data), typeof(object), typeof(CascaderItem));
public bool IsChecked
{
get { return (bool)GetValue(IsCheckedProperty); }
set { SetValue(IsCheckedProperty, value); }
}
public static readonly DependencyProperty IsCheckedProperty =
DependencyProperty.Register(nameof(IsChecked), typeof(bool), typeof(CascaderItem), new PropertyMetadata(false));
public ObservableCollection<CascaderItem> Children
{
get { return (ObservableCollection<CascaderItem>)GetValue(ChildrenProperty); }
set { SetValue(ChildrenProperty, value); }
}
public static readonly DependencyProperty ChildrenProperty =
DependencyProperty.Register(nameof(Children), typeof(ObservableCollection<CascaderItem>), typeof(CascaderItem));
internal CascaderItem ParentTree { get; set; }
}
}
......@@ -76,6 +76,8 @@
<ItemGroup>
<Compile Include="Assist\ButtonAssist.cs" />
<Compile Include="Assist\DataGridAssist.cs" />
<Compile Include="Controls\CascaderItem.cs" />
<Compile Include="Controls\Cascader.cs" />
<Compile Include="Controls\ChildWindow.cs" />
<Compile Include="Controls\ComboBoxControl.cs" />
<Compile Include="Controls\DateTimePicker.cs" />
......@@ -110,6 +112,10 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\CascaderStyle.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Themes\SwitchStyle.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
......@@ -183,5 +189,8 @@
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<Folder Include="Base\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:smart="clr-namespace:SmartUI.Controls"
xmlns:base="clr-namespace:SmartUI.Base"
xmlns:c="clr-namespace:CalcBinding;assembly=CalcBinding">
<Style x:Key="CascaderDefaultStyle" TargetType="{x:Type smart:Cascader}">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="{DynamicResource PrimaryBorderGaryColor}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Width" Value="150"/>
<Setter Property="Height" Value="35"/>
<Setter Property="Margin" Value="0 3"/>
<Setter Property="Foreground" Value="{DynamicResource PrimaryTextColor}"/>
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Auto" />
<Setter Property="Padding" Value="2" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="HorizontalAlignment" Value="Stretch"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="IsDropDownOpen" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type smart:Cascader}">
<Grid>
<Border x:Name="border" Background="White" Margin="0 0 5 0" ToolTip="{TemplateBinding Text}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4">
<DockPanel LastChildFill="True" VerticalAlignment="Center" Cursor="Hand">
<smart:PackIcon x:Name="icon" DockPanel.Dock="Right" Width="16" Height="16" Kind="KeyboardArrowDown" Foreground="{TemplateBinding BorderBrush}" Margin="5"/>
<TextBlock Text="{TemplateBinding Text}" Margin="5 0" VerticalAlignment="Center"/>
</DockPanel>
</Border>
<Popup x:Name="popup" IsOpen="{TemplateBinding IsDropDownOpen}" MinWidth="150" Height="Auto" HorizontalAlignment="Left" VerticalOffset="1" MinHeight="100" MaxHeight="300" AllowsTransparency="True">
<Border Background="White" CornerRadius="4" Padding="1 0" Margin="0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1">
<Border.Effect>
<DropShadowEffect Color="LightGray" Opacity="0.3"/>
</Border.Effect>
<StackPanel x:Name="Pack_items" Orientation="Horizontal">
<StackPanel.Resources>
<Style TargetType="ListBox">
<Setter Property="Width" Value="140"/>
<Setter Property="Height" Value="{Binding ElementName=popup,Path=Height}"/>
<Setter Property="BorderBrush" Value="{DynamicResource BorderBaseColor}"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<DockPanel x:Name="dock" LastChildFill="True" Height="30">
<smart:PackIcon x:Name="icon" Kind="KeyboardArrowRight" DockPanel.Dock="Right" Width="16" Height="16" VerticalAlignment="Center" Margin="5 0"/>
<Label Name="lable" Foreground="{DynamicResource PrimaryTextColor}" IsHitTestVisible="True" Content="{Binding DisplayName}" Padding="5 0"/>
</DockPanel>
<ControlTemplate.Triggers>
<Trigger SourceName="dock" Property="IsMouseOver" Value="True">
<Setter TargetName="dock" Property="Background" Value="{DynamicResource BgHoverColor}"/>
</Trigger>
<DataTrigger Binding="{Binding Children.Count}" Value="0">
<Setter TargetName="icon" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding Children}" Value="{x:Null}">
<Setter TargetName="icon" Property="Visibility" Value="Collapsed"/>
</DataTrigger>
<DataTrigger Binding="{Binding IsChecked}" Value="True">
<Setter TargetName="lable" Property="Foreground" Value="{DynamicResource BrandColor}"/>
<Setter TargetName="icon" Property="Foreground" Value="{DynamicResource BrandColor}"/>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
</StackPanel>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsDropDownOpen" Value="True">
<Setter TargetName="icon" Property="Kind" Value="KeyboardArrowUp"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type smart:Cascader}" BasedOn="{StaticResource CascaderDefaultStyle}"/>
</ResourceDictionary>
\ No newline at end of file
......@@ -21,6 +21,6 @@
<SolidColorBrush x:Key="BgBlackColor" Color="#000000"/>
<SolidColorBrush x:Key="BgWhiteColor" Color="#FFFFFF"/>
<SolidColorBrush x:Key="BgTransparentColor" Color="Transparent"/>
<SolidColorBrush x:Key="BgHoverColor" Color="#FAFAFA"/>
<SolidColorBrush x:Key="TextEnabledColor" Color="#C0C4CC"/>
</ResourceDictionary>
\ No newline at end of file
......@@ -28,7 +28,7 @@
<Grid>
<Border x:Name="border" Background="White" Margin="0 0 5 0" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="4">
<DockPanel LastChildFill="True" VerticalAlignment="Center" Cursor="Hand">
<smart:PackIcon x:Name="icon" DockPanel.Dock="Right" Width="24" Height="24" Kind="KeyboardArrowDown" Foreground="{TemplateBinding BorderBrush}"/>
<smart:PackIcon x:Name="icon" DockPanel.Dock="Right" Width="16" Height="16" Kind="KeyboardArrowDown" Foreground="{TemplateBinding BorderBrush}" Margin="5"/>
<TextBlock Text="{TemplateBinding Text}" Margin="5 0" VerticalAlignment="Center"/>
</DockPanel>
</Border>
......@@ -37,7 +37,7 @@
<Border.Effect>
<DropShadowEffect Color="LightGray" Opacity="0.3"/>
</Border.Effect>
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Visible" CanContentScroll="True">
<ScrollViewer HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Auto" CanContentScroll="True">
<ItemsPresenter SnapsToDevicePixels="True"/>
</ScrollViewer>
</Border>
......@@ -73,7 +73,7 @@
<Style TargetType="ComboBoxItem">
<Setter Property="Width" Value="Auto"/>
<Setter Property="Height" Value="30"/>
<Setter Property="Padding" Value="10 3"/>
<Setter Property="Padding" Value="3"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
......@@ -83,7 +83,7 @@
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="#FAFAFA"/>
<Setter Property="Background" Value="{DynamicResource BgHoverColor}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
......
......@@ -18,5 +18,6 @@
<ResourceDictionary Source="pack://application:,,,/SmartUI;component/Themes/CheckBoxStyle.xaml" />
<ResourceDictionary Source="pack://application:,,,/SmartUI;component/Themes/TextBlockStyle.xaml" />
<ResourceDictionary Source="pack://application:,,,/SmartUI;component/Themes/SwitchStyle.xaml" />
<ResourceDictionary Source="pack://application:,,,/SmartUI;component/Themes/CascaderStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
\ No newline at end of file
......@@ -18,8 +18,7 @@
</Border>
<TextBlock x:Name="untext" Text="{TemplateBinding UnCheckText}" FontSize="{TemplateBinding FontSize}" Foreground="{TemplateBinding Background}"/>
<TextBlock x:Name="texted" Text="{TemplateBinding CheckedText}" FontSize="{TemplateBinding FontSize}" Visibility="Collapsed" Foreground="{DynamicResource SuccessColor}"/>
</WrapPanel>
</WrapPanel>
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="border" Property="HorizontalAlignment" Value="Right"/>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册