Merge pull request #114 from unoplatform/dev/agzi/I86-Chip
fix: Move Chip / ChipGroup to Toolkit
This commit is contained in:
Коммит
a62d637b8e
|
@ -0,0 +1,79 @@
|
|||
# Chip
|
||||
|
||||
## Summary
|
||||
|
||||
`Chip` is a compact `ToggleButton` can be used for selection, filters or for a list of action to trigger. `ChipGroup` can be used to display a list of `Chip`.
|
||||
|
||||
## Features
|
||||
|
||||
### Chip
|
||||
|
||||
| Properties | Type | Description | Supported |
|
||||
|--------------------|--------------|------------------------------------------------------------|-----------------|
|
||||
| IsCheckable | bool | Whether the chip can be checked. note: When used inside a ChipGroup, this property will be overwritten by ChipGroup's SelectionMode. | All platforms |
|
||||
| Icon | object | Icon to display on the chip. | All platforms |
|
||||
| IconTemplate | DataTemplate | Template to display as the chip icon. | All platforms |
|
||||
| CanRemove | bool | Whether there's a remove icon on the chip. | All platforms |
|
||||
| RemoveCommand | TODO | TODO | Not implemented |
|
||||
| RemoveEvent | TODO | TODO | Not implemented |
|
||||
|
||||
### ChipGroup
|
||||
|
||||
| Properties | Type | Description | Supported |
|
||||
|--------------------|-------------------|---------------------------------------------------------------|-----------------|
|
||||
| SelectionMode | ChipSelectionMode | Gets or sets the selection behavior. (None, Single, Multiple) | All platforms |
|
||||
| SelectedItem | object | Current selected item. (SelectionMode = Single) | All platforms |
|
||||
| SelectedItems | IList | Current selected items. (SelectionMode = Multiple) | All platforms |
|
||||
| IconTemplate | DataTemplate | IconTemplate to use for each `Chip`. | All platforms |
|
||||
| CanRemove | bool | Whether we display a remove icon for each `Chip` | All platforms |
|
||||
| RemoveCommand | TODO | TODO | Not implemented |
|
||||
| RemoveEvent | TODO | TODO | Not implemented |
|
||||
|
||||
## Usage
|
||||
|
||||
### Chip
|
||||
|
||||
```xml
|
||||
|
||||
<!-- Filled Input Material chip -->
|
||||
<toolkit:Chip Content="Chip"
|
||||
CanRemove="True"
|
||||
Style="{StaticResource MaterialFilledInputChipStyle}"/>
|
||||
|
||||
<!-- Filled Input Material chip chip with icon-->
|
||||
<toolkit:Chip Content="Chip"
|
||||
Style="{StaticResource MaterialFilledInputChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<!-- Icon -->
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
```
|
||||
|
||||
### ChipGroup
|
||||
|
||||
```xml
|
||||
|
||||
<!-- Filled Input Material ChipGroup with static items -->
|
||||
<toolkit:ChipGroup Style="{StaticResource MaterialFilledInputChipGroupStyle}">
|
||||
<toolkit:Chip Content="Chip" />
|
||||
<toolkit:Chip Content="Chip"
|
||||
IsChecked="True" />
|
||||
<toolkit:Chip Content="Chip" />
|
||||
</toolkit:ChipGroup>
|
||||
|
||||
<!-- Filled Choice Material ChipGroup with dynamic items -->
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Items}"
|
||||
Style="{StaticResource MaterialFilledChoiceChipGroupStyle}">
|
||||
|
||||
<!-- Outlined Input ChipGroup with custom thumbnail template -->
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Items}"
|
||||
Style="{StaticResource MaterialOutlinedInputChipGroupStyle}">
|
||||
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<!-- IconTemplate -->
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
```
|
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-100.png
Normal file
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-100.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 1.4 KiB |
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-150.png
Normal file
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-150.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.1 KiB |
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-200.png
Normal file
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-200.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 2.8 KiB |
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-300.png
Normal file
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-300.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 4.5 KiB |
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-400.png
Normal file
Двоичные данные
samples/Uno.Toolkit.Samples/Uno.Toolkit.Samples.Shared/Assets/Avatar.scale-400.png
Normal file
Двоичный файл не отображается.
После Ширина: | Высота: | Размер: 6.3 KiB |
|
@ -0,0 +1,528 @@
|
|||
<Page x:Class="Uno.Toolkit.Samples.Content.Controls.ChipSamplePage"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:converters="using:Uno.Toolkit.Samples.Converters"
|
||||
xmlns:toolkit="using:Uno.Toolkit.UI.Controls"
|
||||
xmlns:android="http://uno.ui/android"
|
||||
xmlns:ios="http://uno.ui/ios"
|
||||
xmlns:sample="using:Uno.Toolkit.Samples"
|
||||
mc:Ignorable="d android ios">
|
||||
|
||||
<Page.Resources>
|
||||
<converters:FromNullToValueConverter x:Key="SingleSelectionToValueConverter"
|
||||
NotNullValue="Selected Item: #"
|
||||
NullValue="No selection" />
|
||||
|
||||
<converters:FromNullToValueConverter x:Key="MultipleSelectionToValueConverter"
|
||||
NotNullValue="Selected Items:"
|
||||
NullValue="No selection" />
|
||||
|
||||
<Style x:Key="HorizontalScrollViewerStyle"
|
||||
TargetType="ScrollViewer">
|
||||
<Setter Property="HorizontalScrollMode"
|
||||
Value="Auto" />
|
||||
<Setter Property="HorizontalScrollBarVisibility"
|
||||
Value="Auto" />
|
||||
<Setter Property="VerticalScrollMode"
|
||||
Value="Disabled" />
|
||||
<Setter Property="VerticalScrollBarVisibility"
|
||||
Value="Hidden" />
|
||||
<Setter Property="Margin"
|
||||
Value="0,10" />
|
||||
</Style>
|
||||
</Page.Resources>
|
||||
|
||||
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
|
||||
<sample:SamplePageLayout>
|
||||
<sample:SamplePageLayout.MaterialTemplate>
|
||||
<DataTemplate>
|
||||
<StackPanel>
|
||||
<!-- MaterialFilledInputChipStyle -->
|
||||
<TextBlock Text="Input - Filled"
|
||||
Margin="0,20,0,0"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialFilledInputChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialFilledInputChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialFilledInputChipStyle}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- MaterialOutlinedInputChipStyle -->
|
||||
<TextBlock Text="Input - Outlined"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialOutlinedInputChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialOutlinedInputChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialOutlinedInputChipStyle}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
|
||||
<!-- MaterialFilledChoiceChipStyle -->
|
||||
<TextBlock Text="Choice - Filled"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialFilledChoiceChipStyle}" />
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialFilledChoiceChipStyle}"
|
||||
IsEnabled="False" />
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialFilledChoiceChipStyle}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- MaterialOutlinedChoiceChipStyle -->
|
||||
<TextBlock Text="Choice - Outlined"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialOutlinedChoiceChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialOutlinedChoiceChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialOutlinedChoiceChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- MaterialFilledFilterChipStyle -->
|
||||
<TextBlock Text="Filter - Filled"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialFilledFilterChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialFilledFilterChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialFilledFilterChipStyle}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- MaterialOutlinedFilterChipStyle -->
|
||||
<TextBlock Text="Filter - Outlined"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialOutlinedFilterChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialOutlinedFilterChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Selected"
|
||||
IsChecked="True"
|
||||
Style="{StaticResource MaterialOutlinedFilterChipStyle}" />
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
|
||||
<!-- MaterialFilledActionChipStyle -->
|
||||
<TextBlock Text="Action - Filled"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialFilledActionChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialFilledActionChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- MaterialOutlinedActionChipStyle -->
|
||||
<TextBlock Text="Action - Outlined"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8">
|
||||
<toolkit:Chip Content="Enabled"
|
||||
Style="{StaticResource MaterialOutlinedActionChipStyle}">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
|
||||
<toolkit:Chip Content="Disabled"
|
||||
Style="{StaticResource MaterialOutlinedActionChipStyle}"
|
||||
IsEnabled="False">
|
||||
<toolkit:Chip.Icon>
|
||||
<Image Source="ms-appx:///Assets/Avatar.png" />
|
||||
</toolkit:Chip.Icon>
|
||||
</toolkit:Chip>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- ### ChipGroup -->
|
||||
<TextBlock Text="ChipGroup"
|
||||
Margin="0,36,0,20"
|
||||
Style="{StaticResource MaterialHeadline6}" />
|
||||
|
||||
<!-- ChipGroup Input -->
|
||||
<TextBlock Text="Input"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.MutableTestCollection}"
|
||||
ItemRemoved="RemoveChipItem"
|
||||
Style="{StaticResource MaterialFilledInputChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<Image Source="{Binding Image}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.MutableTestCollection}"
|
||||
ItemRemoved="RemoveChipItem"
|
||||
Style="{StaticResource MaterialOutlinedInputChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<Image Source="{Binding Image}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<Button Content="Reset chip items"
|
||||
Click="ResetChipItems"
|
||||
Margin="0,10,0,20" />
|
||||
|
||||
<!-- ChipGroup Choice -->
|
||||
<TextBlock Text="Choice"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialFilledChoiceChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialOutlinedChoiceChipGroupStyle}"
|
||||
SelectionMode="Single"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- ChipGroup Filter -->
|
||||
<TextBlock Text="Filter"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialFilledFilterChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialOutlinedFilterChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<Border Background="{StaticResource MaterialSecondaryBrush}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- ChipGroup Action -->
|
||||
<TextBlock Text="Action"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialFilledActionChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<Image Source="{Binding Image}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup ItemsSource="{Binding Data.TestCollection}"
|
||||
Style="{StaticResource MaterialOutlinedActionChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.IconTemplate>
|
||||
<DataTemplate>
|
||||
<Image Source="{Binding Image}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.IconTemplate>
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<!-- ChipGroup Selection -->
|
||||
<TextBlock Text="Single Selection with Choice chips"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<TextBlock Style="{StaticResource MaterialSubtitle2}">
|
||||
<Run Text="{Binding ElementName=SingleSelectionChipGroup, Path=SelectedItem, Mode=TwoWay, Converter={StaticResource SingleSelectionToValueConverter}}" /><Run Text="{Binding ElementName=SingleSelectionChipGroup, Path=SelectedItem.Index, Mode=TwoWay}" />
|
||||
</TextBlock>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup x:Name="SingleSelectionChipGroup"
|
||||
ItemsSource="{Binding Data.TestArray}"
|
||||
SelectedItem="{Binding Data.TestItem}"
|
||||
Style="{StaticResource MaterialFilledChoiceChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<TextBlock Text="Single Selection with Enum and Choice chips"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<TextBlock Style="{StaticResource MaterialSubtitle2}">
|
||||
<Run Text="{Binding ElementName=SingleEnumSelectionChipGroup, Path=SelectedItem, Mode=TwoWay, Converter={StaticResource SingleSelectionToValueConverter}}" /><Run Text="{Binding ElementName=SingleEnumSelectionChipGroup, Path=SelectedItem, Mode=TwoWay}" />
|
||||
</TextBlock>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup x:Name="SingleEnumSelectionChipGroup"
|
||||
ItemsSource="{Binding Data.TestEnumArray}"
|
||||
SelectedItem="{Binding Data.TestEnumItem}"
|
||||
Style="{StaticResource MaterialFilledChoiceChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}"
|
||||
Text="{Binding}" />
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
|
||||
<TextBlock Text="Multiple selection with Filter chips"
|
||||
Style="{StaticResource MaterialSubtitle1}" />
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Text="{Binding ElementName=MultipleSelectionChipGroup, Path=SelectedItems, Mode=TwoWay, Converter={StaticResource MultipleSelectionToValueConverter}}"
|
||||
Style="{StaticResource MaterialSubtitle2}"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,4,0" />
|
||||
<ItemsControl ItemsSource="{Binding ElementName=MultipleSelectionChipGroup, Path=SelectedItems, Mode=TwoWay}"
|
||||
VerticalAlignment="Center">
|
||||
<ItemsControl.ItemsPanel>
|
||||
<ItemsPanelTemplate>
|
||||
<StackPanel Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
</ItemsControl.ItemsPanel>
|
||||
<ItemsControl.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Margin="0,0,2,0"
|
||||
Style="{StaticResource MaterialSubtitle2}">
|
||||
<Run Text="#" /><Run Text="{Binding Index}" /><Run Text="," />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</ItemsControl.ItemTemplate>
|
||||
</ItemsControl>
|
||||
</StackPanel>
|
||||
|
||||
<ScrollViewer Style="{StaticResource HorizontalScrollViewerStyle}">
|
||||
|
||||
<toolkit:ChipGroup x:Name="MultipleSelectionChipGroup"
|
||||
ItemsSource="{Binding Data.TestArray}"
|
||||
SelectedItems="{Binding Data.TestSelectedItems}"
|
||||
Style="{StaticResource MaterialFilledFilterChipGroupStyle}"
|
||||
Margin="8,0,8,8">
|
||||
|
||||
<toolkit:ChipGroup.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<TextBlock Style="{StaticResource MaterialBody1}">
|
||||
<Run Text="Item #" /><Run Text="{Binding Index}" />
|
||||
</TextBlock>
|
||||
</DataTemplate>
|
||||
</toolkit:ChipGroup.ItemTemplate>
|
||||
</toolkit:ChipGroup>
|
||||
</ScrollViewer>
|
||||
</StackPanel>
|
||||
</DataTemplate>
|
||||
</sample:SamplePageLayout.MaterialTemplate>
|
||||
</sample:SamplePageLayout>
|
||||
</Grid>
|
||||
</Page>
|
|
@ -0,0 +1,66 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices.WindowsRuntime;
|
||||
using Windows.Foundation;
|
||||
using Windows.Foundation.Collections;
|
||||
using Uno.Toolkit.Samples.Entities.Data;
|
||||
using Uno.Toolkit.Samples.Entities;
|
||||
using Uno.Toolkit.UI.Controls;
|
||||
#if IS_WINUI
|
||||
using Microsoft.UI;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using Microsoft.UI.Xaml.Media;
|
||||
using Microsoft.UI.Xaml.Navigation;
|
||||
#else
|
||||
using Windows.UI;
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
using Windows.UI.Xaml.Data;
|
||||
using Windows.UI.Xaml.Input;
|
||||
using Windows.UI.Xaml.Media;
|
||||
using Windows.UI.Xaml.Navigation;
|
||||
#endif
|
||||
|
||||
namespace Uno.Toolkit.Samples.Content.Controls
|
||||
{
|
||||
[SamplePage(SampleCategory.Controls, "Chip", SourceSdk.UnoMaterial, DataType = typeof(TestCollections))]
|
||||
public sealed partial class ChipSamplePage : Page
|
||||
{
|
||||
public ChipSamplePage()
|
||||
{
|
||||
this.InitializeComponent();
|
||||
}
|
||||
|
||||
private void RemoveChipItem(object sender, ChipItemEventArgs e)
|
||||
{
|
||||
if (DataContext is Sample sample)
|
||||
{
|
||||
if (sample.Data is TestCollections test)
|
||||
{
|
||||
test.RemoveChipItem(e.Item as TestCollections.SelectableData);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetChipItems(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (DataContext is Sample sample)
|
||||
{
|
||||
if (sample.Data is TestCollections test)
|
||||
{
|
||||
test.ResetChipItems();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#if IS_WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Data;
|
||||
#endif
|
||||
|
||||
namespace Uno.Toolkit.Samples.Converters
|
||||
{
|
||||
public class FromNullToValueConverter : IValueConverter
|
||||
{
|
||||
public object NullValue { get; set; }
|
||||
|
||||
public object NotNullValue { get; set; }
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
if (value == null || value == DependencyProperty.UnsetValue)
|
||||
{
|
||||
return NullValue;
|
||||
}
|
||||
|
||||
return NotNullValue;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, string language)
|
||||
{
|
||||
throw new NotSupportedException();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -11,6 +11,11 @@ namespace Uno.Toolkit.Samples.Entities.Data
|
|||
{
|
||||
public ObservableCollection<SelectableData> MutableTestCollection { get; } = new ObservableCollection<SelectableData>(CreateItems());
|
||||
public ObservableCollection<SelectableData> TestCollection { get; } = new ObservableCollection<SelectableData>(CreateItems());
|
||||
public static IEnumerable<SelectableData> TestArray { get; } = CreateItems();
|
||||
public static IEnumerable<SelectableData> TestSelectedItems { get; } = TestArray.Take(3).ToArray();
|
||||
public static SelectableData TestItem { get; } = TestArray.First();
|
||||
public static IEnumerable<DayOfWeek> TestEnumArray { get; } = new DayOfWeek[] { DayOfWeek.Monday, DayOfWeek.Tuesday, DayOfWeek.Wednesday, DayOfWeek.Thursday, DayOfWeek.Friday, DayOfWeek.Saturday, DayOfWeek.Sunday };
|
||||
public static DayOfWeek TestEnumItem { get; } = DayOfWeek.Monday;
|
||||
|
||||
private static IEnumerable<SelectableData> CreateItems()
|
||||
{
|
||||
|
@ -18,7 +23,7 @@ namespace Uno.Toolkit.Samples.Entities.Data
|
|||
.Select(x => new SelectableData
|
||||
{
|
||||
Index = x,
|
||||
Image = new Uri("ms-appx:///Assets/Cards/Avatar.png"),
|
||||
Image = new Uri("ms-appx:///Assets/Avatar.png"),
|
||||
})
|
||||
.ToArray();
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@ namespace Uno.Toolkit.Samples.Entities
|
|||
Description = attribute.Description;
|
||||
DocumentationLink = attribute.DocumentationLink;
|
||||
Data = CreateData(attribute.DataType);
|
||||
Source = attribute.Source;
|
||||
SortOrder = attribute.SortOrder;
|
||||
|
||||
ViewType = viewType;
|
||||
|
|
|
@ -7,10 +7,11 @@ namespace Uno.Toolkit.Samples.Entities
|
|||
[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = false)]
|
||||
public sealed class SamplePageAttribute : Attribute
|
||||
{
|
||||
public SamplePageAttribute(SampleCategory category, string title)
|
||||
public SamplePageAttribute(SampleCategory category, string title, SourceSdk source = SourceSdk.WinUI)
|
||||
{
|
||||
Category = category;
|
||||
Title = title;
|
||||
Source = source;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -26,6 +27,8 @@ namespace Uno.Toolkit.Samples.Entities
|
|||
|
||||
public Type DataType { get; set; }
|
||||
|
||||
public SourceSdk Source { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Sort order with the same <see cref="Category"/>.
|
||||
/// </summary>
|
||||
|
|
|
@ -19,6 +19,9 @@
|
|||
<DependentUpon>App.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)App.xaml.Navigation.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Content\Controls\ChipSamplePage.xaml.cs">
|
||||
<DependentUpon>ChipSamplePage.xaml</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Controls\ModalDialog.xaml.cs">
|
||||
<DependentUpon>ModalDialog.xaml</DependentUpon>
|
||||
</Compile>
|
||||
|
@ -67,6 +70,7 @@
|
|||
<Compile Include="$(MSBuildThisFileDirectory)Controls\SamplePageLayout.Properties.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Converters\EnumDescriptionConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Converters\FromBoolToValueConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Converters\FromNullToValueConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Converters\FromStringToValueConverter.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Entities\Data\TestCollections.cs" />
|
||||
<Compile Include="$(MSBuildThisFileDirectory)Entities\Design.cs" />
|
||||
|
@ -90,6 +94,10 @@
|
|||
<PRIResource Include="$(MSBuildThisFileDirectory)Strings\en\Resources.resw" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Content\Controls\ChipSamplePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
</Page>
|
||||
<Page Include="$(MSBuildThisFileDirectory)Content\Controls\DividerSamplePage.xaml">
|
||||
<SubType>Designer</SubType>
|
||||
<Generator>MSBuild:Compile</Generator>
|
||||
|
@ -205,6 +213,11 @@
|
|||
<Content Include="$(MSBuildThisFileDirectory)Assets\AppleIcon_Small.scale-200.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\AppleIcon_Small.scale-300.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\AppleIcon_Small.scale-400.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\Avatar.scale-100.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\Avatar.scale-150.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\Avatar.scale-200.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\Avatar.scale-300.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\Avatar.scale-400.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\BackButton-Dark.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\BackButton.png" />
|
||||
<Content Include="$(MSBuildThisFileDirectory)Assets\CloseIcon.scale-100.png" />
|
||||
|
|
|
@ -0,0 +1,198 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Windows.Input;
|
||||
|
||||
#if IS_WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Controls.Primitives;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Controls.Primitives;
|
||||
#endif
|
||||
|
||||
namespace Uno.Toolkit.UI.Controls
|
||||
{
|
||||
[TemplatePart(Name = RemoveButtonName, Type = typeof(Button))]
|
||||
public partial class Chip : ToggleButton
|
||||
{
|
||||
private const string RemoveButtonName = "PART_RemoveButton";
|
||||
|
||||
public event ChipRemovingEventHandler Removing;
|
||||
public event RoutedEventHandler Removed;
|
||||
|
||||
/// <summary>
|
||||
/// Fires when a ToggleButton is checked or unchecked, except when set with <see cref="SetIsCheckedSilently"/>.
|
||||
/// </summary>
|
||||
internal event RoutedEventHandler IsCheckedChanged;
|
||||
|
||||
#region DependencyProperty: IsCheckable = true
|
||||
|
||||
public static DependencyProperty IsCheckableProperty { get; } = DependencyProperty.Register(
|
||||
nameof(IsCheckable),
|
||||
typeof(bool),
|
||||
typeof(Chip),
|
||||
new PropertyMetadata(true, (s, e) => (s as Chip)?.OnIsCheckableChanged(e)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets whether this should behave like a ToggleButton or a Button
|
||||
/// </summary>
|
||||
public bool IsCheckable
|
||||
{
|
||||
get => (bool)GetValue(IsCheckableProperty);
|
||||
set => SetValue(IsCheckableProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: Icon
|
||||
|
||||
public object Icon
|
||||
{
|
||||
get { return (IconElement)GetValue(IconProperty); }
|
||||
set { SetValue(IconProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IconProperty =
|
||||
DependencyProperty.Register("Icon", typeof(object), typeof(Chip), new PropertyMetadata(null));
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: IconTemplate
|
||||
|
||||
public DataTemplate IconTemplate
|
||||
{
|
||||
get { return (DataTemplate)GetValue(IconTemplateProperty); }
|
||||
set { SetValue(IconTemplateProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IconTemplateProperty =
|
||||
DependencyProperty.Register("IconTemplate", typeof(DataTemplate), typeof(Chip), new PropertyMetadata(null));
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: CanRemove = false
|
||||
|
||||
public bool CanRemove
|
||||
{
|
||||
get { return (bool)GetValue(CanRemoveProperty); }
|
||||
set { SetValue(CanRemoveProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CanRemoveProperty =
|
||||
DependencyProperty.Register("CanRemove", typeof(bool), typeof(Chip), new PropertyMetadata(false));
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: RemovedCommand
|
||||
|
||||
public static DependencyProperty RemovedCommandProperty { get; } = DependencyProperty.Register(
|
||||
nameof(RemovedCommand),
|
||||
typeof(ICommand),
|
||||
typeof(Chip),
|
||||
new PropertyMetadata(default));
|
||||
|
||||
public ICommand RemovedCommand
|
||||
{
|
||||
get => (ICommand)GetValue(RemovedCommandProperty);
|
||||
set => SetValue(RemovedCommandProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: RemovedCommandParameter
|
||||
|
||||
public static DependencyProperty RemovedCommandParameterProperty { get; } = DependencyProperty.Register(
|
||||
nameof(RemovedCommandParameter),
|
||||
typeof(object),
|
||||
typeof(Chip),
|
||||
new PropertyMetadata(default));
|
||||
|
||||
public object RemovedCommandParameter
|
||||
{
|
||||
get => (object)GetValue(RemovedCommandParameterProperty);
|
||||
set => SetValue(RemovedCommandParameterProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
private bool _isMuted = false;
|
||||
|
||||
public Chip()
|
||||
{
|
||||
Checked += RaiseIsCheckedChanged;
|
||||
Unchecked += RaiseIsCheckedChanged;
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
|
||||
if (GetTemplateChild(RemoveButtonName) is Button removeButton)
|
||||
{
|
||||
removeButton.Click += RaiseRemoveButtonClicked;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnIsCheckableChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (!IsCheckable)
|
||||
{
|
||||
IsChecked = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseIsCheckedChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (!_isMuted)
|
||||
{
|
||||
IsCheckedChanged?.Invoke(sender, e);
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseRemoveButtonClicked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
// note: sender is the RemoveButton, do not pass it as the event sender
|
||||
// as ChipGroup expect the sender to be an instance of Chip
|
||||
|
||||
if (CanRemove)
|
||||
{
|
||||
var removingArgs = new ChipRemovingEventArgs();
|
||||
Removing?.Invoke(this, removingArgs);
|
||||
|
||||
if (!removingArgs.Cancel)
|
||||
{
|
||||
Removed?.Invoke(this, e);
|
||||
|
||||
var param = RemovedCommandParameter;
|
||||
if (RemovedCommand is ICommand command && command.CanExecute(param))
|
||||
{
|
||||
command.Execute(param);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetIsCheckedSilently(bool? value)
|
||||
{
|
||||
try
|
||||
{
|
||||
_isMuted = true;
|
||||
IsChecked = value;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isMuted = false;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnToggle()
|
||||
{
|
||||
if (!IsCheckable) return;
|
||||
|
||||
base.OnToggle();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,111 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
#if IS_WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
#endif
|
||||
|
||||
namespace Uno.Toolkit.UI.Controls
|
||||
{
|
||||
public partial class ChipGroup
|
||||
{
|
||||
#region DependencyProperty: SelectedItem
|
||||
|
||||
public static DependencyProperty SelectedItemProperty { get; } = DependencyProperty.Register(
|
||||
nameof(SelectedItem),
|
||||
typeof(object),
|
||||
typeof(ChipGroup),
|
||||
new PropertyMetadata(default, (s, e) => (s as ChipGroup)?.OnSelectedItemChanged(e)));
|
||||
|
||||
public object SelectedItem
|
||||
{
|
||||
get => (object)GetValue(SelectedItemProperty);
|
||||
set => SetValue(SelectedItemProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: SelectedItems
|
||||
|
||||
public static DependencyProperty SelectedItemsProperty { get; } = DependencyProperty.Register(
|
||||
nameof(SelectedItems),
|
||||
typeof(IList),
|
||||
typeof(ChipGroup),
|
||||
new PropertyMetadata(default, (s, e) => (s as ChipGroup)?.OnSelectedItemsChanged(e)));
|
||||
|
||||
public IList SelectedItems
|
||||
{
|
||||
get => (IList)GetValue(SelectedItemsProperty);
|
||||
set => SetValue(SelectedItemsProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: SelectionMemberPath
|
||||
|
||||
public static DependencyProperty SelectionMemberPathProperty { get; } = DependencyProperty.Register(
|
||||
nameof(SelectionMemberPath),
|
||||
typeof(string),
|
||||
typeof(ChipGroup),
|
||||
new PropertyMetadata(default, (s, e) => (s as ChipGroup)?.OnSelectionMemberPathChanged(e)));
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name or path of the property that indicates selection state for each data item.
|
||||
/// </summary>
|
||||
public string SelectionMemberPath
|
||||
{
|
||||
get => (string)GetValue(SelectionMemberPathProperty);
|
||||
set => SetValue(SelectionMemberPathProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: SelectionMode = ChipSelectionMode.Single
|
||||
|
||||
public static DependencyProperty SelectionModeProperty { get; } = DependencyProperty.Register(
|
||||
nameof(SelectionMode),
|
||||
typeof(ChipSelectionMode),
|
||||
typeof(ChipGroup),
|
||||
new PropertyMetadata(ChipSelectionMode.Single, (s, e) => (s as ChipGroup)?.OnSelectionModeChanged(e)));
|
||||
|
||||
public ChipSelectionMode SelectionMode
|
||||
{
|
||||
get => (ChipSelectionMode)GetValue(SelectionModeProperty);
|
||||
set => SetValue(SelectionModeProperty, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: IconTemplate
|
||||
|
||||
public DataTemplate IconTemplate
|
||||
{
|
||||
get { return (DataTemplate)GetValue(IconTemplateProperty); }
|
||||
set { SetValue(IconTemplateProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty IconTemplateProperty =
|
||||
DependencyProperty.Register("IconTemplate", typeof(DataTemplate), typeof(ChipGroup), new PropertyMetadata(null, (s, e) => (s as ChipGroup)?.ApplyIconTemplate()));
|
||||
|
||||
#endregion
|
||||
|
||||
#region DependencyProperty: CanRemove = false
|
||||
|
||||
// TODO : Implement Remove Command/Event
|
||||
|
||||
public bool CanRemove
|
||||
{
|
||||
get { return (bool)GetValue(CanRemoveProperty); }
|
||||
set { SetValue(CanRemoveProperty, value); }
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty CanRemoveProperty =
|
||||
DependencyProperty.Register("CanRemove", typeof(bool), typeof(ChipGroup), new PropertyMetadata(false, (s, e) => (s as ChipGroup)?.ApplyCanRemoveProperty()));
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,436 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using Uno.Extensions.Specialized;
|
||||
|
||||
#if IS_WINUI
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Data;
|
||||
#else
|
||||
using Windows.UI.Xaml;
|
||||
using Windows.UI.Xaml.Controls;
|
||||
using Windows.UI.Xaml.Data;
|
||||
#endif
|
||||
|
||||
namespace Uno.Toolkit.UI.Controls
|
||||
{
|
||||
public partial class ChipGroup : ItemsControl
|
||||
{
|
||||
public event ChipItemEventHandler ItemClick;
|
||||
public event ChipItemEventHandler ItemChecked;
|
||||
public event ChipItemEventHandler ItemUnchecked;
|
||||
public event ChipItemRemovingEventHandler ItemRemoving;
|
||||
public event ChipItemEventHandler ItemRemoved;
|
||||
|
||||
private bool _isLoaded = false;
|
||||
private bool _isSynchronizingSelection = false;
|
||||
private bool _isUpdatingSelection = false;
|
||||
|
||||
public ChipGroup()
|
||||
{
|
||||
RegisterPropertyChangedCallback(ItemsSourceProperty, (s, e) => (s as ChipGroup)?.OnItemsSourceChanged());
|
||||
|
||||
this.Loaded += OnLoaded;
|
||||
}
|
||||
|
||||
protected override void OnApplyTemplate()
|
||||
{
|
||||
base.OnApplyTemplate();
|
||||
}
|
||||
|
||||
private void OnLoaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
_isLoaded = true;
|
||||
SynchronizeInitialSelection();
|
||||
EnforceSelectionMode();
|
||||
ApplyIconTemplate();
|
||||
}
|
||||
|
||||
private void OnSelectionMemberPathChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var binding = SelectionMemberPath != null
|
||||
? new Binding { Path = new PropertyPath(SelectionMemberPath), Mode = BindingMode.TwoWay }
|
||||
: null;
|
||||
foreach (var container in GetItemContainers())
|
||||
{
|
||||
if (binding != null)
|
||||
{
|
||||
container.SetBinding(Chip.IsCheckedProperty, binding);
|
||||
}
|
||||
|
||||
container.ClearValue(Chip.IsCheckedProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyIconTemplate()
|
||||
{
|
||||
if (IconTemplate != null)
|
||||
{
|
||||
foreach (var container in GetItemContainers())
|
||||
{
|
||||
container.Icon = container.Content;
|
||||
container.IconTemplate = IconTemplate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ApplyCanRemoveProperty()
|
||||
{
|
||||
foreach (var container in GetItemContainers())
|
||||
{
|
||||
container.CanRemove = CanRemove;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectionModeChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
EnforceSelectionMode();
|
||||
}
|
||||
|
||||
private void OnItemIsCheckedChanged(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isSynchronizingSelection) return;
|
||||
if (sender is Chip container)
|
||||
{
|
||||
UpdateSelection(new[] { container });
|
||||
}
|
||||
}
|
||||
|
||||
protected override void OnItemsChanged(object e)
|
||||
{
|
||||
base.OnItemsChanged(e);
|
||||
|
||||
SynchronizeInitialSelection();
|
||||
EnforceSelectionMode();
|
||||
}
|
||||
|
||||
protected void OnItemsSourceChanged()
|
||||
{
|
||||
SynchronizeInitialSelection();
|
||||
EnforceSelectionMode();
|
||||
}
|
||||
|
||||
private void OnSelectedItemChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (_isSynchronizingSelection || _isUpdatingSelection) return;
|
||||
|
||||
if (!IsReady && e.NewValue != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectionMode == ChipSelectionMode.Single && FindContainer(SelectedItem) is Chip container)
|
||||
{
|
||||
container.SetIsCheckedSilently(true);
|
||||
UpdateSelection(new[] { container });
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSelection(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnSelectedItemsChanged(DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (_isSynchronizingSelection || _isUpdatingSelection) return;
|
||||
|
||||
if (!IsReady && e.NewValue != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectionMode == ChipSelectionMode.Multiple)
|
||||
{
|
||||
var selectedContainers = SelectedItems
|
||||
?.Cast<object>()
|
||||
.Select(x => FindContainer(x))
|
||||
.Where(x => x != null)
|
||||
.ToArray();
|
||||
|
||||
foreach (var container in selectedContainers ?? Enumerable.Empty<Chip>())
|
||||
{
|
||||
container.SetIsCheckedSilently(true);
|
||||
}
|
||||
|
||||
UpdateSelection(selectedContainers, forceClearOthersSelection: true);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSelection(null, forceClearOthersSelection: true);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected override bool IsItemItsOwnContainerOverride(object item) => item is Chip;
|
||||
|
||||
protected override DependencyObject GetContainerForItemOverride() => new Chip();
|
||||
|
||||
protected override void PrepareContainerForItemOverride(DependencyObject element, object item)
|
||||
{
|
||||
base.PrepareContainerForItemOverride(element, item);
|
||||
|
||||
if (element is Chip container)
|
||||
{
|
||||
if (SelectionMemberPath != null)
|
||||
{
|
||||
container.SetBinding(Chip.IsCheckedProperty, new Binding { Path = new PropertyPath(SelectionMemberPath), Mode = BindingMode.TwoWay });
|
||||
}
|
||||
|
||||
if (IconTemplate != null)
|
||||
{
|
||||
container.Icon = container.Content;
|
||||
container.IconTemplate = IconTemplate;
|
||||
}
|
||||
|
||||
container.IsChecked = IsItemSelected(item);
|
||||
container.CanRemove = CanRemove;
|
||||
|
||||
container.IsCheckedChanged += OnItemIsCheckedChanged;
|
||||
container.Click += OnItemClick;
|
||||
container.Checked += OnItemChecked;
|
||||
container.Unchecked += OnItemUnchecked;
|
||||
container.Removing += OnItemRemoving;
|
||||
container.Removed += OnItemRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsItemSelected(object item)
|
||||
{
|
||||
// It's important to use Equals and not == because of boxing.
|
||||
return Equals(item, SelectedItem) || (SelectedItems?.Contains(item) ?? false);
|
||||
}
|
||||
|
||||
protected override void ClearContainerForItemOverride(DependencyObject element, object item)
|
||||
{
|
||||
base.ClearContainerForItemOverride(element, item);
|
||||
|
||||
if (element is Chip container)
|
||||
{
|
||||
container.ClearValue(Chip.IsCheckedProperty);
|
||||
|
||||
container.Icon = null;
|
||||
container.IconTemplate = null;
|
||||
container.CanRemove = false;
|
||||
|
||||
container.IsCheckedChanged -= OnItemIsCheckedChanged;
|
||||
container.Click -= OnItemClick;
|
||||
container.Checked -= OnItemChecked;
|
||||
container.Unchecked -= OnItemUnchecked;
|
||||
container.Removing -= OnItemRemoving;
|
||||
container.Removed -= OnItemRemoved;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnItemClick(object sender, RoutedEventArgs e) => RaiseItemEvent(ItemClick, sender);
|
||||
|
||||
private void OnItemChecked(object sender, RoutedEventArgs e) => RaiseItemEvent(ItemChecked, sender);
|
||||
|
||||
private void OnItemUnchecked(object sender, RoutedEventArgs e) => RaiseItemEvent(ItemUnchecked, sender);
|
||||
|
||||
private void OnItemRemoving(object sender, ChipRemovingEventArgs e)
|
||||
{
|
||||
if (sender is Chip container)
|
||||
{
|
||||
var args = new ChipItemRemovingEventArgs(ItemFromContainer(container));
|
||||
args.Cancel = e.Cancel;
|
||||
|
||||
ItemRemoving?.Invoke(this, new ChipItemRemovingEventArgs(ItemFromContainer(container)));
|
||||
e.Cancel = args.Cancel;
|
||||
}
|
||||
}
|
||||
|
||||
private void OnItemRemoved(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is Chip container)
|
||||
{
|
||||
// there isn't much that can be done here if the item is generated from an ItemsSource
|
||||
// in such case, the removal should be handled from the source provider (view-model or code-behind)
|
||||
|
||||
// remove the item only if it was added via xaml or .Add(item)
|
||||
if (ItemsSource == null &&
|
||||
Items?.IndexOf(container) is int index && index != -1)
|
||||
{
|
||||
Items.RemoveAt(index);
|
||||
}
|
||||
|
||||
RaiseItemEvent(ItemRemoved, sender);
|
||||
}
|
||||
}
|
||||
|
||||
private void RaiseItemEvent(ChipItemEventHandler handler, object originalSender)
|
||||
{
|
||||
if (originalSender is Chip container)
|
||||
{
|
||||
handler?.Invoke(this, new ChipItemEventArgs(ItemFromContainer(container)));
|
||||
}
|
||||
}
|
||||
|
||||
private void SynchronizeInitialSelection()
|
||||
{
|
||||
if (!IsReady)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (SelectedItem != null)
|
||||
{
|
||||
OnSelectedItemChanged(null);
|
||||
}
|
||||
|
||||
if (SelectedItems != null)
|
||||
{
|
||||
OnSelectedItemsChanged(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void EnforceSelectionMode()
|
||||
{
|
||||
if (!IsReady) return;
|
||||
|
||||
if (SelectionMode == ChipSelectionMode.None)
|
||||
{
|
||||
UpdateItemsIsCheckable();
|
||||
UpdateSelection(default);
|
||||
}
|
||||
else if (SelectionMode == ChipSelectionMode.Single)
|
||||
{
|
||||
UpdateItemsIsCheckable();
|
||||
|
||||
// either one is selected or none are selected
|
||||
var selectedContainers = GetItemContainers().Where(x => x.IsChecked ?? false).ToArray();
|
||||
if (selectedContainers.Length > 1)
|
||||
{
|
||||
foreach (var container in selectedContainers)
|
||||
{
|
||||
container.SetIsCheckedSilently(false);
|
||||
}
|
||||
UpdateSelection(default);
|
||||
}
|
||||
else
|
||||
{
|
||||
UpdateSelection(selectedContainers);
|
||||
}
|
||||
}
|
||||
else if (SelectionMode == ChipSelectionMode.Multiple)
|
||||
{
|
||||
UpdateItemsIsCheckable();
|
||||
UpdateSelection(default);
|
||||
}
|
||||
|
||||
void UpdateItemsIsCheckable()
|
||||
{
|
||||
foreach (var container in GetItemContainers())
|
||||
{
|
||||
container.IsCheckable = SelectionMode != ChipSelectionMode.None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void UpdateSelection(Chip[] newlySelectedContainers, bool forceClearOthersSelection = false)
|
||||
{
|
||||
if (!IsReady) return;
|
||||
if (_isSynchronizingSelection) return;
|
||||
|
||||
try
|
||||
{
|
||||
_isSynchronizingSelection = true;
|
||||
|
||||
var selectedItems = new List<object>();
|
||||
foreach (var container in GetItemContainers())
|
||||
{
|
||||
if (!container.IsChecked ?? false)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (ShouldClearSelection())
|
||||
{
|
||||
container.SetIsCheckedSilently(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
selectedItems.Add(ItemFromContainer(container));
|
||||
}
|
||||
|
||||
bool ShouldClearSelection()
|
||||
{
|
||||
switch (SelectionMode)
|
||||
{
|
||||
case ChipSelectionMode.None:
|
||||
// uncheck all
|
||||
return true;
|
||||
case ChipSelectionMode.Single:
|
||||
// uncheck every other items
|
||||
return newlySelectedContainers?.Contains(container) != true;
|
||||
case ChipSelectionMode.Multiple:
|
||||
// uncheck other items if SelectedItem or SelectedItems got updated
|
||||
return forceClearOthersSelection && newlySelectedContainers?.Contains(container) != true;
|
||||
|
||||
default: throw new ArgumentOutOfRangeException(nameof(SelectionMode));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update selection properties
|
||||
SelectedItem = SelectionMode == ChipSelectionMode.Single && selectedItems?.Count == 1
|
||||
? selectedItems[0]
|
||||
: null;
|
||||
SelectedItems = SelectionMode == ChipSelectionMode.Multiple && selectedItems?.Count >= 1
|
||||
? selectedItems
|
||||
: null;
|
||||
}
|
||||
finally
|
||||
{
|
||||
_isSynchronizingSelection = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsReady => _isLoaded && HasItems && HasContainers;
|
||||
|
||||
private bool HasItems => GetItems().Any();
|
||||
|
||||
private bool HasContainers => GetItemContainers().Any();
|
||||
|
||||
/// <summary>
|
||||
/// Get the items.
|
||||
/// </summary>
|
||||
/// <remarks>The item itself maybe its own container, as in the case of <see cref="Chip"> added as child to <see cref="ItemsControl.Items"/>.</remarks>
|
||||
private IEnumerable GetItems() =>
|
||||
ItemsSource as IEnumerable ??
|
||||
(ItemsSource as CollectionViewSource)?.View ??
|
||||
Items ??
|
||||
Enumerable.Empty<object>();
|
||||
|
||||
private Chip FindContainer(object item)
|
||||
{
|
||||
if (item == null) return null;
|
||||
|
||||
// For some obscure reason, ContainerFromItem returns null when item is an enum.
|
||||
// Note however that it works fine for other value types such as int.
|
||||
// Because of this, we retrieve the container using the index instead.
|
||||
if (item is Enum)
|
||||
{
|
||||
var index = GetItems().IndexOf(item);
|
||||
if (index != -1)
|
||||
{
|
||||
return ContainerFromIndex(index) as Chip;
|
||||
}
|
||||
}
|
||||
|
||||
return
|
||||
item as Chip ??
|
||||
ContainerFromItem(item) as Chip;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get the item containers.
|
||||
/// </summary>
|
||||
/// <remarks>An empty enumerable will returned if the <see cref="ItemsControl.ItemsPanelRoot"/> and the containers have not been materialized.</remarks>
|
||||
private IEnumerable<Chip> GetItemContainers() =>
|
||||
ItemsPanelRoot?.Children.OfType<Chip>() ??
|
||||
Enumerable.Empty<Chip>();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Uno.Toolkit.UI.Controls
|
||||
{
|
||||
public enum ChipSelectionMode
|
||||
{
|
||||
None, Single, Multiple,
|
||||
}
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Uno.Toolkit.UI.Controls
|
||||
{
|
||||
#region Chip event handlers
|
||||
public delegate void ChipRemovingEventHandler(object sender, ChipRemovingEventArgs e);
|
||||
public sealed class ChipRemovingEventArgs : EventArgs
|
||||
{
|
||||
public bool Cancel { get; set; }
|
||||
}
|
||||
|
||||
public delegate void ChipRemovedEventHandler(object sender, EventArgs e);
|
||||
#endregion
|
||||
|
||||
|
||||
#region ChipGroup event handlers
|
||||
public delegate void ChipItemEventHandler(object sender, ChipItemEventArgs e);
|
||||
public class ChipItemEventArgs : EventArgs
|
||||
{
|
||||
internal ChipItemEventArgs(object item) => Item = item;
|
||||
|
||||
public object Item { get; }
|
||||
}
|
||||
|
||||
public delegate void ChipItemRemovingEventHandler(object sender, ChipItemEventArgs e);
|
||||
public class ChipItemRemovingEventArgs : ChipItemEventArgs
|
||||
{
|
||||
public ChipItemRemovingEventArgs(object item) : base(item) { }
|
||||
|
||||
public bool Cancel { get; set; }
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
|
@ -31,6 +31,8 @@ namespace Uno.Toolkit.UI.Material
|
|||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/TopTabBar.Mobile.xaml") });
|
||||
#else
|
||||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/BottomTabBar.xaml") });
|
||||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/Chip.xaml") });
|
||||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/ChipGroup.xaml") });
|
||||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/TopTabBar.xaml") });
|
||||
#endif
|
||||
this.MergedDictionaries.Add(new ResourceDictionary { Source = new Uri($"ms-appx:///{PackageName}/Styles/Controls/Divider.xaml") });
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -0,0 +1,142 @@
|
|||
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:toolkitLib="using:Uno.Toolkit.UI.Controls"
|
||||
xmlns:win="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:android="http://uno.ui/android"
|
||||
xmlns:ios="http://uno.ui/ios"
|
||||
xmlns:wasm="http://uno.ui/wasm"
|
||||
xmlns:macos="http://uno.ui/macos"
|
||||
xmlns:toolkit="using:Uno.UI.Toolkit"
|
||||
mc:Ignorable="android ios wasm macos">
|
||||
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="Chip.xaml" />
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
|
||||
<ItemsPanelTemplate x:Key="MaterialHorizontalChipGroupItemsPanel">
|
||||
<StackPanel Orientation="Horizontal"
|
||||
Spacing="8" />
|
||||
</ItemsPanelTemplate>
|
||||
|
||||
<Style x:Key="BaseMaterialChipGroupStyle"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemsPanel"
|
||||
Value="{StaticResource MaterialHorizontalChipGroupItemsPanel}" />
|
||||
</Style>
|
||||
|
||||
<!-- Begin Input Chip Group Style -->
|
||||
<Style x:Key="MaterialFilledInputChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialFilledInputChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="True" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Multiple" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MaterialOutlinedInputChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialOutlinedInputChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="True" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Multiple" />
|
||||
</Style>
|
||||
<!-- End Input Chip Group Style -->
|
||||
|
||||
<!-- Begin Choice Chip Group Style -->
|
||||
<Style x:Key="MaterialFilledChoiceChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialFilledChoiceChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Single" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MaterialOutlinedChoiceChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialOutlinedChoiceChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Single" />
|
||||
</Style>
|
||||
<!-- End Choice Chip Group Style -->
|
||||
|
||||
<!-- Begin Filter Chip Group Style -->
|
||||
<Style x:Key="MaterialFilledFilterChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialFilledFilterChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Multiple" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MaterialOutlinedFilterChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialOutlinedFilterChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="Multiple" />
|
||||
</Style>
|
||||
<!-- End Filter Chip Group Style -->
|
||||
|
||||
<!-- Begin Action Chip Group Style -->
|
||||
<Style x:Key="MaterialFilledActionChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialFilledActionChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="None" />
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MaterialOutlinedActionChipGroupStyle"
|
||||
BasedOn="{StaticResource BaseMaterialChipGroupStyle}"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialOutlinedActionChipStyle}" />
|
||||
<Setter Property="CanRemove"
|
||||
Value="False" />
|
||||
<Setter Property="SelectionMode"
|
||||
Value="None" />
|
||||
</Style>
|
||||
<!-- End Action Chip Group Style -->
|
||||
|
||||
<!--
|
||||
ItemsWrapGrid is not working inside an ItemsControl.
|
||||
Issue (WASM) https://github.com/unoplatform/uno/issues/468
|
||||
(All platforms) https://github.com/unoplatform/uno/issues/4023
|
||||
-->
|
||||
<!--<ItemsPanelTemplate x:Key="MaterialWrapChipGroupItemsPanel">
|
||||
<ItemsWrapGrid Orientation="Horizontal" />
|
||||
</ItemsPanelTemplate>
|
||||
|
||||
|
||||
<Style x:Key="MaterialWrapChipGroupStyle"
|
||||
TargetType="toolkitLib:ChipGroup">
|
||||
<Setter Property="ItemsPanel"
|
||||
Value="{StaticResource MaterialWrapChipGroupItemsPanel}" />
|
||||
<Setter Property="ItemContainerStyle"
|
||||
Value="{StaticResource MaterialChipStyle}" />
|
||||
</Style>-->
|
||||
|
||||
</ResourceDictionary>
|
Загрузка…
Ссылка в новой задаче