Merge pull request #263 from irihitech/multicombo

Fix MultiComboBox container selection state issue.
This commit is contained in:
Dong Bin
2024-06-24 23:32:15 +08:00
committed by GitHub
4 changed files with 30 additions and 11 deletions

View File

@@ -17,6 +17,7 @@
InnerLeftContent="Left" InnerLeftContent="Left"
InnerRightContent="Right" InnerRightContent="Right"
Classes="ClearButton" Classes="ClearButton"
MaxHeight="200"
ItemsSource="{Binding Items}" > ItemsSource="{Binding Items}" >
</u:MultiComboBox> </u:MultiComboBox>
<ListBox ItemsSource="{Binding #combo.SelectedItems}" /> <ListBox ItemsSource="{Binding #combo.SelectedItems}" />

View File

@@ -60,13 +60,6 @@
</ItemsControl.ItemsPanel> </ItemsControl.ItemsPanel>
</u:MultiComboBoxSelectedItemList> </u:MultiComboBoxSelectedItemList>
</ScrollViewer> </ScrollViewer>
<Button
Name="ClearButton"
Grid.Column="2"
Command="{Binding $parent[u:MultiComboBox].Clear}"
Content="{DynamicResource IconButtonClearData}"
IsVisible="False"
Theme="{DynamicResource InnerIconButton}" />
<ContentPresenter <ContentPresenter
Grid.Column="3" Grid.Column="3"
Margin="8,0" Margin="8,0"
@@ -84,10 +77,18 @@
Margin="0,0,10,0" Margin="0,0,10,0"
HorizontalAlignment="Right" HorizontalAlignment="Right"
VerticalAlignment="Center" VerticalAlignment="Center"
IsVisible="{Binding #ClearButton.IsVisible, Converter={x:Static BoolConverters.Not}}"
Data="{DynamicResource ComboBoxIcon}" Data="{DynamicResource ComboBoxIcon}"
Foreground="{DynamicResource ComboBoxIconDefaultForeground}" Foreground="{DynamicResource ComboBoxIconDefaultForeground}"
IsHitTestVisible="False" IsHitTestVisible="False"
UseLayoutRounding="False" /> UseLayoutRounding="False" />
<Button
Name="ClearButton"
Grid.Column="4"
Command="{Binding $parent[u:MultiComboBox].Clear}"
Content="{DynamicResource IconButtonClearData}"
IsVisible="False"
Theme="{DynamicResource InnerIconButton}" />
</Grid> </Grid>
</Border> </Border>
<Popup <Popup

View File

@@ -6,6 +6,7 @@ using Avalonia.Controls;
using Avalonia.Controls.Metadata; using Avalonia.Controls.Metadata;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Templates; using Avalonia.Controls.Templates;
using Avalonia.Data.Converters;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
@@ -54,7 +55,7 @@ public class MultiComboBox: SelectingItemsControl, IInnerContentControl
} }
public new static readonly StyledProperty<IList?> SelectedItemsProperty = AvaloniaProperty.Register<MultiComboBox, IList?>( public new static readonly StyledProperty<IList?> SelectedItemsProperty = AvaloniaProperty.Register<MultiComboBox, IList?>(
nameof(SelectedItems), new AvaloniaList<object>()); nameof(SelectedItems));
public new IList? SelectedItems public new IList? SelectedItems
{ {
@@ -99,10 +100,12 @@ public class MultiComboBox: SelectingItemsControl, IInnerContentControl
public MultiComboBox() public MultiComboBox()
{ {
SelectedItems = new AvaloniaList<object>();
if (SelectedItems is INotifyCollectionChanged c) if (SelectedItems is INotifyCollectionChanged c)
{ {
c.CollectionChanged+=OnSelectedItemsCollectionChanged; c.CollectionChanged+= OnSelectedItemsCollectionChanged;
} }
} }
private void OnSelectedItemsChanged(AvaloniaPropertyChangedEventArgs<IList?> args) private void OnSelectedItemsChanged(AvaloniaPropertyChangedEventArgs<IList?> args)
@@ -117,7 +120,7 @@ public class MultiComboBox: SelectingItemsControl, IInnerContentControl
} }
} }
private void OnSelectedItemsCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) private void OnSelectedItemsCollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
{ {
PseudoClasses.Set(PC_Empty, SelectedItems?.Count == 0); PseudoClasses.Set(PC_Empty, SelectedItems?.Count == 0);
} }

View File

@@ -4,6 +4,7 @@ using Avalonia.Controls;
using Avalonia.Controls.Mixins; using Avalonia.Controls.Mixins;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.LogicalTree; using Avalonia.LogicalTree;
using Irihi.Avalonia.Shared.Common;
using Irihi.Avalonia.Shared.Helpers; using Irihi.Avalonia.Shared.Helpers;
namespace Ursa.Controls; namespace Ursa.Controls;
@@ -13,6 +14,7 @@ public class MultiComboBoxItem: ContentControl
private MultiComboBox? _parent; private MultiComboBox? _parent;
private static readonly Point s_invalidPoint = new (double.NaN, double.NaN); private static readonly Point s_invalidPoint = new (double.NaN, double.NaN);
private Point _pointerDownPoint = s_invalidPoint; private Point _pointerDownPoint = s_invalidPoint;
private bool _updateInternal;
public static readonly StyledProperty<bool> IsSelectedProperty = AvaloniaProperty.Register<MultiComboBoxItem, bool>( public static readonly StyledProperty<bool> IsSelectedProperty = AvaloniaProperty.Register<MultiComboBoxItem, bool>(
nameof(IsSelected)); nameof(IsSelected));
@@ -25,7 +27,7 @@ public class MultiComboBoxItem: ContentControl
static MultiComboBoxItem() static MultiComboBoxItem()
{ {
IsSelectedProperty.AffectsPseudoClass<MultiComboBoxItem>(":selected"); IsSelectedProperty.AffectsPseudoClass<MultiComboBoxItem>(PseudoClassName.PC_Selected);
PressedMixin.Attach<MultiComboBoxItem>(); PressedMixin.Attach<MultiComboBoxItem>();
FocusableProperty.OverrideDefaultValue<MultiComboBoxItem>(true); FocusableProperty.OverrideDefaultValue<MultiComboBoxItem>(true);
IsSelectedProperty.Changed.AddClassHandler<MultiComboBoxItem, bool>((item, args) => IsSelectedProperty.Changed.AddClassHandler<MultiComboBoxItem, bool>((item, args) =>
@@ -34,6 +36,7 @@ public class MultiComboBoxItem: ContentControl
private void OnSelectionChanged(AvaloniaPropertyChangedEventArgs<bool> args) private void OnSelectionChanged(AvaloniaPropertyChangedEventArgs<bool> args)
{ {
if (_updateInternal) return;
var parent = this.FindLogicalAncestorOfType<MultiComboBox>(); var parent = this.FindLogicalAncestorOfType<MultiComboBox>();
if (args.NewValue.Value) if (args.NewValue.Value)
{ {
@@ -94,4 +97,15 @@ public class MultiComboBoxItem: ContentControl
} }
} }
} }
protected override void OnAttachedToVisualTree(VisualTreeAttachmentEventArgs e)
{
base.OnAttachedToVisualTree(e);
_updateInternal = true;
if (_parent?.ItemsPanelRoot is VirtualizingPanel)
{
IsSelected = _parent?.SelectedItems?.Contains(DataContext) ?? false;
}
_updateInternal = false;
}
} }