Skip to content

Commit

Permalink
Merge pull request #12 from thomasgalliker/children-property-refactoring
Browse files Browse the repository at this point in the history
Merge children-property-refactoring into develop
  • Loading branch information
thomasgalliker authored Jul 24, 2024
2 parents d1f2ebf + 39ac02b commit 08cb846
Show file tree
Hide file tree
Showing 8 changed files with 105 additions and 35 deletions.
5 changes: 4 additions & 1 deletion .editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -169,4 +169,7 @@ dotnet_naming_style.static_field_style.capitalization = pascal_case
dotnet_diagnostic.CS4014.severity = error

# IDE0051: Remove unused private members
dotnet_diagnostic.IDE0051.severity = warning
dotnet_diagnostic.IDE0051.severity = warning

# CS1591: Missing XML comment for publicly visible type or member
dotnet_diagnostic.CS1591.severity = none
64 changes: 40 additions & 24 deletions Plugin.SegmentedControl.Maui/Controls/SegmentedControl.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public SegmentedControl()

public event EventHandler<SelectedIndexChangedEventArgs> SelectedIndexChanged;

public static readonly BindableProperty ChildrenProperty = BindableProperty.Create(
private static readonly BindableProperty ChildrenProperty = BindableProperty.Create(
nameof(Children),
typeof(IList<SegmentedControlOption>),
typeof(SegmentedControl),
Expand All @@ -34,7 +34,7 @@ public SegmentedControl()
public IList<SegmentedControlOption> Children
{
get => (IList<SegmentedControlOption>)this.GetValue(ChildrenProperty);
set => this.SetValue(ChildrenProperty, value);
private set => this.SetValue(ChildrenProperty, value);
}

private static void OnChildrenPropertyChanging(BindableObject bindable, object oldValue, object newValue)
Expand Down Expand Up @@ -67,42 +67,58 @@ public IEnumerable ItemsSource

private void OnItemsSourcePropertyChanged()
{
var itemsSource = this.ItemsSource;
var items = itemsSource as IList;
if (items == null && itemsSource is IEnumerable list)
List<SegmentedControlOption> segmentedControlOptions;

if (this.ItemsSource is IEnumerable<SegmentedControlOption> s)
{
items = list.Cast<object>().ToList();
segmentedControlOptions = s.ToList();
}

if (items != null)
else
{
var textValues = items as IEnumerable<string>;
if (textValues == null && items.Count > 0 && items[0] is string)
{
textValues = items.Cast<string>();
}
var itemsSource = this.ItemsSource;
var items = itemsSource as IList;

if (textValues != null)
if (items == null && itemsSource is IEnumerable enumerable)
{
this.Children = new List<SegmentedControlOption>(textValues.Select(child => new SegmentedControlOption { Text = child }));
this.OnSelectedItemPropertyChanged(true);
items = enumerable.Cast<object>().ToList();
}
else

if (items != null)
{
var textPropertyName = this.TextPropertyName;
if (textPropertyName != null)
var textValues = items as IEnumerable<string>;
if (textValues == null && items.Count > 0 && items[0] is string)
{
textValues = items.Cast<string>();
}

if (textValues != null)
{
segmentedControlOptions = textValues
.Select(t => new SegmentedControlOption { Text = t })
.ToList();
}
else
{
var newChildren = new List<SegmentedControlOption>();
segmentedControlOptions = new List<SegmentedControlOption>();
var textPropertyName = this.TextPropertyName;
foreach (var item in items)
{
newChildren.Add(new SegmentedControlOption { Item = item, TextPropertyName = textPropertyName });
segmentedControlOptions.Add(new SegmentedControlOption
{
Item = item,
TextPropertyName = textPropertyName
});
}

this.Children = newChildren;
this.OnSelectedItemPropertyChanged(true);
}
}
else
{
segmentedControlOptions = new List<SegmentedControlOption>();
}
}

this.Children = segmentedControlOptions;
this.OnSelectedItemPropertyChanged(true);
}

protected override void OnPropertyChanged(string propertyName = null)
Expand Down
21 changes: 18 additions & 3 deletions Plugin.SegmentedControl.Maui/Controls/SegmentedControlOption.cs
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,25 @@ private void OnItemPropertyChanged(object sender, PropertyChangedEventArgs e)

private void SetTextFromItemProperty()
{
if (this.Item != null && this.TextPropertyName != null)
if (this.Item is object item)
{
var propertyInfo = this.Item.GetType().GetProperty(this.TextPropertyName);
this.Text = propertyInfo?.GetValue(this.Item)?.ToString();
if (this.TextPropertyName is string textPropertyName && !string.IsNullOrEmpty(textPropertyName))
{
var itemType = item.GetType();
var propertyInfo = itemType.GetProperty(textPropertyName);
if (propertyInfo == null)
{
throw new ArgumentException($"Property '{textPropertyName}' could not be found on object of type {itemType.FullName}", nameof(this.TextPropertyName));
}
else
{
this.Text = propertyInfo.GetValue(item)?.ToString();
}
}
else
{
this.Text = item.ToString();
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,12 @@
<RepositoryUrl>https://github.com/thomasgalliker/Plugin.SegmentedControl.Maui</RepositoryUrl>
<Company>superdev GmbH</Company>
<GeneratePackageOnBuild>false</GeneratePackageOnBuild>
<PackageReleaseNotes>1.1
<PackageReleaseNotes>1.2
- Children property is no longer public; use ItemsSource instead
- Improved error handling in SegmentedControlOption
- Several bug fixes and internal refactorings

1.1
- Add new properties FontFamily, FontSize, FontAttributes

1.0
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<MauiVersion>8.0.70</MauiVersion>
<SingleProject>true</SingleProject>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<Nullable>disable</Nullable>

<!-- Display name -->
<ApplicationTitle>SegmentedControlDemoApp</ApplicationTitle>
Expand Down
26 changes: 25 additions & 1 deletion Samples/SegmentedControlDemoApp/Views/Test1Page.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,31 @@
Spacing="20"
VerticalOptions="Start">

<Label Text="Example with segment options defined in XAML. All style properties are left with default values. WidthRequest=160." />
<Label Text="Example with an embedded string array as segment options defined in XAML.&#10;All style properties are left with default values." />

<s:SegmentedControl>
<s:SegmentedControl.ItemsSource>
<x:Array Type="{x:Type x:String}">
<x:String>Tab 1</x:String>
<x:String>Tab 2</x:String>
<x:String>Tab 3</x:String>
</x:Array>
</s:SegmentedControl.ItemsSource>
</s:SegmentedControl>

<Label Text="Example with an array of SegmentedControlOptions set as ItemsSource." />

<s:SegmentedControl>
<s:SegmentedControl.ItemsSource>
<x:Array Type="{x:Type s:SegmentedControlOption}">
<s:SegmentedControlOption Text="Tab1" />
<s:SegmentedControlOption Text="Tab2" />
<s:SegmentedControlOption Text="Tab3" />
</x:Array>
</s:SegmentedControl.ItemsSource>
</s:SegmentedControl>

<Label Text="Example with SegmentedControlOptions defined in XAML. Events subscribed in code-behind.&#10;No styles applied. WidthRequest=160." />

<s:SegmentedControl
x:Name="SegmentedControl"
Expand Down
9 changes: 8 additions & 1 deletion Samples/SegmentedControlDemoApp/Views/Test3Page.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@
Spacing="20"
VerticalOptions="Start">

<Label Text="Example with data binding complex item view models to ItemsSource and SegmentedItem" />
<Label Text="Example with data binding complex item view models to ItemsSource and SelectedItem" />

<s:SegmentedControl
ItemsSource="{Binding Countries}"
SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"
TextPropertyName="EnglishName" />

<Label Text="Example with data binding complex item view models but leaving the TextPropertyName empty." />

<s:SegmentedControl
ItemsSource="{Binding Countries}"
SelectedItem="{Binding SelectedCountry, Mode=TwoWay}"
TextPropertyName="{x:Null}" />

<Grid BackgroundColor="{StaticResource Gray100}">
<Label Text="{Binding SelectedCountry.OfficialName, StringFormat='{}SelectedCountry: {0}'}" />
</Grid>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,16 @@ public void ShouldRaiseSegmentSelectedEvent()

private static SegmentedControl CreateSegmentedControl()
{
// Arrange
return new SegmentedControl
var segmentedControl = new SegmentedControl
{
Children = new[]
ItemsSource = new[]
{
new SegmentedControlOption { Text = "Tab 1" },
new SegmentedControlOption { Text = "Tab 2" },
new SegmentedControlOption { Text = "Tab 3" },
},
};
return segmentedControl;
}
}
}

0 comments on commit 08cb846

Please sign in to comment.