Skip to content

Commit 5822b76

Browse files
committed
Fix issue: MultiSelectComboBox support single multiple columns (#195
1 parent 4064236 commit 5822b76

5 files changed

Lines changed: 128 additions & 43 deletions

File tree

src/WPFDevelopers.Shared/Controls/MultiSelectComboBox/MultiSelectComboBox.cs

Lines changed: 73 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -215,18 +215,19 @@ protected override void PrepareContainerForItemOverride(DependencyObject element
215215
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
216216
{
217217
base.OnSelectionChanged(e);
218+
if (!IsLoaded) return;
218219
if (SelectedItems != null)
219220
{
220221
foreach (var item in e.AddedItems)
221222
{
222223
if (!SelectedItems.Contains(item))
223224
{
224-
SelectedItems.Add(item);
225+
TrySelectItem(item);
225226
}
226227
}
227228
foreach (var item in e.RemovedItems)
228229
{
229-
SelectedItems.Remove(item);
230+
TryUnselectItem(item);
230231
}
231232
if (!_isUpdating && SelectedItemsExt != null)
232233
{
@@ -317,7 +318,14 @@ public override void OnApplyTemplate()
317318
AddHandler(Controls.Tag.CloseEvent, new RoutedEventHandler(Tags_Close));
318319
_panel = GetTemplateChild(PART_SimpleWrapPanel) as Panel;
319320
}
321+
UpdateText();
320322
SyncListViewViews();
323+
Loaded += OnMultiSelectComboBox_Loaded;
324+
}
325+
326+
private void OnMultiSelectComboBox_Loaded(object sender, RoutedEventArgs e)
327+
{
328+
UpdateText();
321329
}
322330

323331
public MultiSelectComboBox()
@@ -448,7 +456,7 @@ private void OnDataGridSearch_SelectionChanged(object sender, SelectionChangedEv
448456
if (_listViewSearch.Items.Contains(item))
449457
{
450458
if (SelectedItems.Contains(item))
451-
SelectedItems.Remove(item);
459+
TryUnselectItem(item);
452460
}
453461

454462
if (selectedList.Contains(item))
@@ -464,7 +472,7 @@ private void OnDataGridSearch_SelectionChanged(object sender, SelectionChangedEv
464472
foreach (var item in e.AddedItems)
465473
{
466474
if (!SelectedItems.Contains(item))
467-
SelectedItems.Add(item);
475+
TrySelectItem(item);
468476
}
469477

470478
UpdateText();
@@ -569,9 +577,24 @@ private void SearchText(string text)
569577
selectedItems.Clear();
570578
foreach (var item in _listViewSearch.Items)
571579
{
580+
//if (SelectedItems.Contains(item))
581+
// if (!_listViewSearch.SelectedItems.Contains(item))
582+
// _listViewSearch.SelectedItems.Add(item);
572583
if (SelectedItems.Contains(item))
584+
{
573585
if (!_listViewSearch.SelectedItems.Contains(item))
574-
_listViewSearch.SelectedItems.Add(item);
586+
{
587+
if (SelectionMode == SelectionMode.Single)
588+
{
589+
_listViewSearch.SelectedItem = item;
590+
}
591+
else
592+
{
593+
if (!_listViewSearch.SelectedItems.Contains(item))
594+
_listViewSearch.SelectedItems.Add(item);
595+
}
596+
}
597+
}
575598
}
576599
}
577600
}
@@ -721,13 +744,21 @@ void CreateTag(object item, MultiSelectComboBoxItem multiSelectComboBoxItem = nu
721744
if (ItemsSource != null && (!string.IsNullOrEmpty(SelectedValuePath) || !string.IsNullOrEmpty(DisplayMemberPath)))
722745
{
723746
var bindingPath = !string.IsNullOrEmpty(SelectedValuePath) ? SelectedValuePath : DisplayMemberPath;
724-
var binding = new Binding(bindingPath) { Source = item };
725-
tag.SetBinding(ContentControl.ContentProperty, binding);
747+
var property = item.GetType().GetProperty(bindingPath);
748+
if (property != null && property.GetValue(item, null) != null)
749+
{
750+
var binding = new Binding(bindingPath) { Source = item };
751+
tag.SetBinding(ContentControl.ContentProperty, binding);
752+
}
753+
else
754+
tag.Content = item;
755+
//var binding = new Binding(bindingPath) { Source = item };
756+
//tag.SetBinding(ContentControl.ContentProperty, binding);
726757
}
727758
else
728759
{
729-
if (multiSelectComboBoxItem != null)
730-
tag.Content = multiSelectComboBoxItem.Content;
760+
if (item != null)
761+
tag.Content = item;
731762
}
732763
}
733764

@@ -753,13 +784,13 @@ private void Tags_Close(object sender, RoutedEventArgs e)
753784
{
754785
if (SelectedItems.Contains(item))
755786
{
756-
SelectedItems.Remove(item);
787+
TryUnselectItem(item);
757788
}
758789
else
759790
{
760791
var match = Items.Cast<object>().FirstOrDefault(h => this.GetDisplayAndSelectedValue(h).ToString() == this.GetDisplayAndSelectedValue(item).ToString());
761792
if (match != null && SelectedItems.Contains(match))
762-
SelectedItems.Remove(match);
793+
TryUnselectItem(match);
763794
}
764795
}
765796
}
@@ -793,7 +824,7 @@ private static void OnSelectedItemsExtChanged(DependencyObject d, DependencyProp
793824
model = ctrl.ItemsSource.OfType<object>()
794825
.FirstOrDefault(h => h == item);
795826
if (model != null && !ctrl.SelectedItems.Contains(item))
796-
ctrl.SelectedItems.Add(model);
827+
ctrl.TrySelectItem(model);
797828

798829
}
799830
ctrl._isUpdating = false;
@@ -812,7 +843,7 @@ private void OnSelectedItemsExtCollectionChanged(object sender, NotifyCollection
812843
foreach (var item in e.OldItems)
813844
{
814845
if (SelectedItems.Contains(item))
815-
SelectedItems.Remove(item);
846+
TryUnselectItem(item);
816847
}
817848
}
818849

@@ -821,11 +852,39 @@ private void OnSelectedItemsExtCollectionChanged(object sender, NotifyCollection
821852
foreach (var item in e.NewItems)
822853
{
823854
if (!SelectedItems.Contains(item))
824-
SelectedItems.Add(item);
855+
TrySelectItem(item);
825856
}
826857
}
827858
_isUpdating = false;
828859
}
860+
861+
private void TrySelectItem(object item)
862+
{
863+
if (SelectionMode == SelectionMode.Single)
864+
{
865+
SelectedItem = item;
866+
}
867+
else
868+
{
869+
if (!SelectedItems.Contains(item))
870+
SelectedItems.Add(item);
871+
}
872+
}
873+
874+
private void TryUnselectItem(object item)
875+
{
876+
if (SelectionMode == SelectionMode.Single)
877+
{
878+
if (Equals(SelectedItem, item))
879+
SelectedItem = null;
880+
}
881+
else
882+
{
883+
if (SelectedItems.Contains(item))
884+
SelectedItems.Remove(item);
885+
}
886+
}
887+
829888
}
830889
public enum ShowType
831890
{

src/WPFDevelopers.Shared/Controls/MultiSelectComboBox/MultiSelectComboBoxItem.cs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,24 @@ private void OnItemPreviewMouseLeftButtonDown(object sender, MouseButtonEventArg
4848
{
4949
if (IsClickInside<CheckBox>(e.OriginalSource as DependencyObject))
5050
return;
51-
IsSelected = !IsSelected;
51+
var listView = ItemsControl.ItemsControlFromItemContainer(this) as ListView;
52+
if (listView != null && listView.SelectionMode == SelectionMode.Single)
53+
{
54+
foreach (var item in listView.Items)
55+
{
56+
var container = listView.ItemContainerGenerator.ContainerFromItem(item) as MultiSelectComboBoxItem;
57+
if (container != null && container != this)
58+
{
59+
container.IsSelected = false;
60+
}
61+
}
62+
IsSelected = true;
63+
}
64+
else
65+
{
66+
IsSelected = !IsSelected;
67+
}
68+
//IsSelected = !IsSelected;
5269
e.Handled = true;
5370
}
5471

src/WPFDevelopers.Shared/Core/Helpers/SelectorHelper.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ private static object GetPropertyValueByPath(object item, string path)
3434
if (currentObject == null) return null;
3535

3636
var property = currentObject.GetType().GetProperty(part);
37-
if (property == null) return null;
37+
if (property == null) return item;
3838

3939
currentObject = property.GetValue(currentObject, null);
4040
}

src/WPFDevelopers.Shared/Styles/Styles.ListView.xaml

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -85,13 +85,12 @@
8585
</Setter>
8686
</Style>
8787

88-
8988
<Style
9089
x:Key="WD.DefaultGridViewColumnHeader"
9190
BasedOn="{StaticResource WD.ControlBasicStyle}"
9291
TargetType="{x:Type GridViewColumnHeader}">
93-
<Setter Property="HorizontalContentAlignment" Value="Left" />
94-
<Setter Property="VerticalContentAlignment" Value="Center" />
92+
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, FallbackValue=Stretch}" />
93+
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListView}}, FallbackValue=Center}" />
9594
<Setter Property="Background" Value="{DynamicResource WD.BackgroundBrush}" />
9695
<Setter Property="BorderBrush" Value="{DynamicResource WD.BaseBrush}" />
9796
<Setter Property="BorderThickness" Value="0,0,0,1" />
@@ -102,26 +101,32 @@
102101
<Setter Property="Template">
103102
<Setter.Value>
104103
<ControlTemplate TargetType="{x:Type GridViewColumnHeader}">
105-
<controls:SmallPanel>
106-
<Border
107-
x:Name="HeaderBorder"
108-
Padding="{TemplateBinding Padding}"
109-
Background="{TemplateBinding Background}"
110-
BorderBrush="{TemplateBinding BorderBrush}"
111-
BorderThickness="{TemplateBinding BorderThickness}">
104+
<Border
105+
x:Name="HeaderBorder"
106+
Background="{TemplateBinding Background}"
107+
BorderBrush="{TemplateBinding BorderBrush}"
108+
BorderThickness="{TemplateBinding BorderThickness}">
109+
<Grid>
110+
<Grid.ColumnDefinitions>
111+
<ColumnDefinition Width="Auto" />
112+
<ColumnDefinition Width="*" />
113+
<ColumnDefinition Width="8" />
114+
</Grid.ColumnDefinitions>
112115
<ContentPresenter
113116
x:Name="HeaderContent"
117+
Margin="{TemplateBinding Padding}"
114118
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
115119
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
116120
RecognizesAccessKey="True"
117121
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
118122
TextElement.FontWeight="{TemplateBinding FontWeight}" />
119-
</Border>
120-
<Thumb
121-
x:Name="PART_HeaderGripper"
122-
HorizontalAlignment="Right"
123-
Style="{StaticResource WD.GridViewColumnHeaderGripper}" />
124-
</controls:SmallPanel>
123+
<Thumb
124+
x:Name="PART_HeaderGripper"
125+
Grid.Column="2"
126+
Width="8"
127+
Style="{StaticResource WD.GridViewColumnHeaderGripper}" />
128+
</Grid>
129+
</Border>
125130
</ControlTemplate>
126131
</Setter.Value>
127132
</Setter>

src/WPFDevelopers.Shared/Themes/MultiSelectComboBox.xaml

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
x:Key="WD.DefaultMultiSelectComboBoxItem"
1212
BasedOn="{StaticResource WD.ControlBasicStyle}"
1313
TargetType="{x:Type controls:MultiSelectComboBoxItem}">
14-
<Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
15-
<Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
14+
<Setter Property="HorizontalContentAlignment" Value="Left" />
15+
<Setter Property="VerticalContentAlignment" Value="Center" />
1616
<Setter Property="SnapsToDevicePixels" Value="True" />
1717
<Setter Property="Background" Value="Transparent" />
1818
<Setter Property="BorderBrush" Value="Transparent" />
@@ -34,7 +34,7 @@
3434
<CheckBox
3535
MinHeight="{TemplateBinding MinHeight}"
3636
Margin="{Binding Padding, RelativeSource={RelativeSource AncestorType=ListViewItem}}"
37-
HorizontalAlignment="Stretch"
37+
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
3838
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
3939
helpers:ElementHelper.CornerRadius="{Binding Path=(helpers:ElementHelper.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
4040
Foreground="{TemplateBinding Foreground}"
@@ -46,15 +46,18 @@
4646
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
4747
Content="{TemplateBinding Content}"
4848
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
49-
5049
</CheckBox>
51-
<GridViewRowPresenter
52-
x:Name="PART_GridViewRowPresenter"
53-
Margin="{Binding Padding, RelativeSource={RelativeSource AncestorType=ListViewItem}, Converter={StaticResource WD.DirectionalThicknessConverter}, ConverterParameter=vertical}"
54-
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
55-
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
56-
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
57-
Visibility="{Binding View, RelativeSource={RelativeSource AncestorType={x:Type controls:MultiSelectComboBox}}, Converter={StaticResource WD.NullToVisibilityConverter_Inverse}}" />
50+
<Border
51+
x:Name="PART_GridViewContainer"
52+
Padding="{Binding Padding, RelativeSource={RelativeSource AncestorType=ListViewItem}, Converter={StaticResource WD.DirectionalThicknessConverter}, ConverterParameter=vertical}"
53+
Background="Transparent"
54+
Visibility="{Binding View, RelativeSource={RelativeSource AncestorType={x:Type controls:MultiSelectComboBox}}, Converter={StaticResource WD.NullToVisibilityConverter_Inverse}}">
55+
<GridViewRowPresenter
56+
x:Name="PART_GridViewRowPresenter"
57+
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
58+
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
59+
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
60+
</Border>
5861
</controls:SmallPanel>
5962
</Border>
6063
<ControlTemplate.Triggers>
@@ -268,6 +271,7 @@
268271
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
269272
VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"
270273
helpers:ElementHelper.CornerRadius="{Binding Path=(helpers:ElementHelper.CornerRadius), RelativeSource={RelativeSource TemplatedParent}}"
274+
BorderThickness="0"
271275
DisplayMemberPath="{TemplateBinding DisplayMemberPath}"
272276
ItemContainerStyle="{TemplateBinding ItemContainerStyle}"
273277
ItemsSource="{TemplateBinding ItemsSourceSearch}"

0 commit comments

Comments
 (0)