diff --git a/source/iNKORE.UI.WPF.Modern.Gallery/Controls/SampleCodePresenter.xaml.cs b/source/iNKORE.UI.WPF.Modern.Gallery/Controls/SampleCodePresenter.xaml.cs index 3b75f16..355bc31 100644 --- a/source/iNKORE.UI.WPF.Modern.Gallery/Controls/SampleCodePresenter.xaml.cs +++ b/source/iNKORE.UI.WPF.Modern.Gallery/Controls/SampleCodePresenter.xaml.cs @@ -2,6 +2,7 @@ using ICSharpCode.AvalonEdit; using ICSharpCode.AvalonEdit.Editing; using ICSharpCode.AvalonEdit.Highlighting; +using iNKORE.UI.WPF.Modern.Gallery.Helpers; using SamplesCommon; using System; using System.Collections.Generic; @@ -158,32 +159,13 @@ private void FormatAndRenderSampleFromString(string sampleString, TextEditor pre if (presenter.SyntaxHighlighting != highlighter) presenter.SyntaxHighlighting = highlighter; - - if (sampleString != presenter.Text) - presenter.Text = RemoveLeadingAndTrailingEmptyLines(sampleString); + var formattedText = StringHelper.RemoveLeadingAndTrailingEmptyLines(sampleString); + if (formattedText != presenter.Text) + presenter.Text = formattedText; presenter.Visibility = Visibility.Visible; } - static string RemoveLeadingAndTrailingEmptyLines(string text) - { - if (string.IsNullOrWhiteSpace(text)) - return string.Empty; - - var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); - int start = 0; - while (start < lines.Length && string.IsNullOrWhiteSpace(lines[start])) - start++; - - int end = lines.Length - 1; - while (end >= start && string.IsNullOrWhiteSpace(lines[end])) - end--; - - var trimmedLines = lines.Skip(start).Take(end - start + 1); - return string.Join(Environment.NewLine, trimmedLines); - } - - private void CopyCodeButton_Click(object sender, RoutedEventArgs e) { try diff --git a/source/iNKORE.UI.WPF.Modern.Gallery/Helpers/StringHelper.cs b/source/iNKORE.UI.WPF.Modern.Gallery/Helpers/StringHelper.cs new file mode 100644 index 0000000..abc2ee2 --- /dev/null +++ b/source/iNKORE.UI.WPF.Modern.Gallery/Helpers/StringHelper.cs @@ -0,0 +1,42 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace iNKORE.UI.WPF.Modern.Gallery.Helpers +{ + public static class StringHelper + { + public static string fIndent(this string text, double indent, bool doFirstLine = false) + { + string[] lines = RemoveLeadingAndTrailingEmptyLines(text).Split('\n'); + string indentStr = new string(' ', (int)(indent * 4)); + for (int i = 0; i < lines.Length; i++) + { + if (i == 0 && !doFirstLine) continue; + lines[i] = indentStr + lines[i]; + } + return string.Join('\n', lines); + } + + public static string RemoveLeadingAndTrailingEmptyLines(this string text) + { + if (string.IsNullOrWhiteSpace(text)) + return string.Empty; + + var lines = text.Split(new[] { "\r\n", "\r", "\n" }, StringSplitOptions.None); + int start = 0; + while (start < lines.Length && string.IsNullOrWhiteSpace(lines[start])) + start++; + + int end = lines.Length - 1; + while (end >= start && string.IsNullOrWhiteSpace(lines[end])) + end--; + + var trimmedLines = lines.Skip(start).Take(end - start + 1); + return string.Join(Environment.NewLine, trimmedLines); + } + + } +} diff --git a/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml b/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml index bef2694..0d93c41 100644 --- a/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml +++ b/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml @@ -14,7 +14,7 @@ SnapsToDevicePixels="True" mc:Ignorable="d"> - + - @@ -386,26 +366,38 @@ - - - - - + + + + - + - + - + + SelectedItem="{Binding Source={StaticResource uniformGridLayout}, Path=Orientation}" + SelectionChanged="RadioButtons_SelectionChanged"/> @@ -413,10 +405,10 @@ - - + + - + @@ -432,9 +424,8 @@ - @@ -442,16 +433,24 @@ - - - - + + + + SelectedItem="{Binding Source={StaticResource flowLayout}, Path=LineAlignment}" + SelectionChanged="RadioButtons_SelectionChanged"/> diff --git a/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml.cs b/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml.cs index 29fd5c1..02c3801 100644 --- a/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml.cs +++ b/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ItemsRepeaterPage.xaml.cs @@ -1,4 +1,5 @@ using iNKORE.UI.WPF.Modern.Controls; +using iNKORE.UI.WPF.Modern.Gallery.Helpers; using System; using System.Collections.Generic; using System.Collections.ObjectModel; @@ -33,6 +34,10 @@ public ItemsRepeaterPage() InitializeData(); repeater2.ItemsSource = Enumerable.Range(0, 500); repeater.ItemsSource = BarItems; + + // UpdateExampleCode(); + VStackBtn.RaiseEvent(new RoutedEventArgs(RadioButton.ClickEvent)); + Ex2_CustomLayout.RaiseEvent(new RoutedEventArgs(RadioButton.ClickEvent)); } ~ItemsRepeaterPage() @@ -41,70 +46,49 @@ public ItemsRepeaterPage() private void InitializeData() { - if (BarItems == null) - { - BarItems = new ObservableCollection(); - } + if (BarItems == null) BarItems = new ObservableCollection(); + BarItems.Add(new Bar(300, this.MaxLength)); BarItems.Add(new Bar(25, this.MaxLength)); BarItems.Add(new Bar(175, this.MaxLength)); - List basicData = new List(); - basicData.Add(64); - basicData.Add("Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."); - basicData.Add(128); - basicData.Add("Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."); - basicData.Add(256); - basicData.Add("Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."); - basicData.Add(512); - basicData.Add("Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."); - basicData.Add(1024); + List basicData = + [ + 64, + "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.", + 128, + "Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", + 256, + "Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.", + 512, + "Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.", + 1024, + ]; MixedTypeRepeater.ItemsSource = basicData; - List nestedCategories = new List(); - nestedCategories.Add( - new NestedCategory("Fruits", new ObservableCollection{ - "Apricots", - "Bananas", - "Grapes", - "Strawberries", - "Watermelon", - "Plums", - "Blueberries" - })); - - nestedCategories.Add( - new NestedCategory("Vegetables", new ObservableCollection{ - "Broccoli", - "Spinach", - "Sweet potato", - "Cauliflower", - "Onion", - "Brussel sprouts", - "Carrots" - })); - - nestedCategories.Add( - new NestedCategory("Grains", new ObservableCollection{ - "Rice", - "Quinoa", - "Pasta", - "Bread", - "Farro", - "Oats", - "Barley" - })); - - nestedCategories.Add( - new NestedCategory("Proteins", new ObservableCollection{ - "Steak", - "Chicken", - "Tofu", - "Salmon", - "Pork", - "Chickpeas", - "Eggs" - })); + List nestedCategories = + [ + new NestedCategory("Fruits", new ObservableCollection + { + "Apricots", "Bananas", "Grapes", "Strawberries", + "Watermelon", "Plums", "Blueberries" + }), + new NestedCategory("Vegetables", new ObservableCollection + { + "Broccoli", "Spinach", "Sweet potato", "Cauliflower", + "Onion", "Brussel sprouts", "Carrots" + }), + new NestedCategory("Grains", new ObservableCollection + { + "Rice", "Quinoa", "Pasta", "Bread", + "Farro", "Oats", "Barley" + }), + new NestedCategory("Proteins", new ObservableCollection + { + "Steak", "Chicken", "Tofu", "Salmon", + "Pork", "Chickpeas", "Eggs" + }), + ]; outerRepeater.ItemsSource = nestedCategories; } @@ -147,15 +131,34 @@ private void OrientationBtn_Click(object sender, RoutedEventArgs e) repeater.ItemsSource = BarItems; isHorizontal = !isHorizontal; + UpdateExampleCode(); } + + private string _repeater2_Layout = ""; private void LayoutBtn_Click(object sender, RoutedEventArgs e) { string layoutKey = ((FrameworkElement)sender).Tag as string; + if (layoutKey.Equals(nameof(this.VerticalStackLayout))) // we used x:Name in the resources which both acts as the x:Key value and creates a member field by the same name + { + _repeater2_Layout = _code_VerticalStackLayout; + } + else if (layoutKey.Equals(nameof(this.HorizontalStackLayout))) + { + _repeater2_Layout = _code_HorizontalStackLayout; + } + else if (layoutKey.Equals(nameof(this.UniformGridLayout))) + { + _repeater2_Layout = _code_UniformGridLayout; + } repeater2.Layout = Resources[layoutKey] as VirtualizingLayout; + UpdateExampleCode(); } + private string repeaterLayoutCode = ""; + private string repeaterItemTemplate = ""; + private void RadioBtn_Click(object sender, RoutedEventArgs e) { string itemTemplateKey = String.Empty; @@ -164,24 +167,33 @@ private void RadioBtn_Click(object sender, RoutedEventArgs e) if (layoutKey.Equals(nameof(this.VerticalStackLayout))) // we used x:Name in the resources which both acts as the x:Key value and creates a member field by the same name { itemTemplateKey = "HorizontalBarTemplate"; + repeaterItemTemplate = _code_HorizontalBarTemplate; + repeaterLayoutCode = _code_VerticalStackLayout; repeater.MaxWidth = MaxLength + 12; } else if (layoutKey.Equals(nameof(this.HorizontalStackLayout))) { itemTemplateKey = "VerticalBarTemplate"; + repeaterItemTemplate = _code_VerticalBarTemplate; + repeaterLayoutCode = _code_HorizontalStackLayout; repeater.MaxWidth = 6000; } else if (layoutKey.Equals(nameof(this.UniformGridLayout))) { itemTemplateKey = "CircularTemplate"; + repeaterItemTemplate = _code_CircularTemplate; + repeaterLayoutCode = _code_UniformGridLayout; repeater.MaxWidth = 540; } + repeater.Layout = Resources[layoutKey] as VirtualizingLayout; repeater.ItemTemplate = Resources[itemTemplateKey] as DataTemplate; repeater.ItemsSource = BarItems; + + UpdateExampleCode(); } private async void OnLoaded(object sender, RoutedEventArgs e) @@ -209,13 +221,486 @@ private void ModifyFirstItemButton_Click(object sender, RoutedEventArgs e) } } + private void NumberBox_ValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args) + { + UpdateExampleCode(); + } + + private void RadioButtons_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + UpdateExampleCode(); + } + + #region Example Code public void UpdateExampleCode() { - + if (!this.IsInitialized) return; + + Example1.Xaml = Example1Xaml; + Example1.CSharp = Example1CS; + Example2.Xaml = Example2Xaml; + Example2.CSharp = Example2CS; + Example3.Xaml = Example3Xaml; + Example3.CSharp = Example3CS; + Example4.Xaml = Example4Xaml; + Example4.CSharp = Example4CS; + + Example5.Xaml = Example5Xaml; + Example5.CSharp = Example5CS; + Example6.Xaml = Example6Xaml; + Example6.CSharp = Example6CS; + Example7.Xaml = Example7Xaml; + Example7.CSharp = Example7CS; } + #region Page Overview + + private static readonly string _code_HorizontalBarTemplate = $@" + + + + + +"; + private static readonly string _code_VerticalBarTemplate = $@" + + + + + +"; + private static readonly string _code_CircularTemplate = $@" + + + + + + +"; + + private static readonly string _code_VerticalStackLayout = $@" + +"; + private static readonly string _code_HorizontalStackLayout = $@" + +"; + private static readonly string _code_UniformGridLayout = $@" + +"; + + public string Example1Xaml => $@" + + + + + {repeaterItemTemplate.fIndent(4)} + + + {repeaterLayoutCode.fIndent(4)} + + + + +"; + public string Example1CS => $@" +public class Bar +{{ + public Bar(double length, int max) + {{ + Length = length; + MaxLength = max; + + Height = length / 4; + MaxHeight = max / 4; + + Diameter = length / 6; + MaxDiameter = max / 6; + }} + public double Length {{ get; set; }} + public int MaxLength {{ get; set; }} + + public double Height {{ get; set; }} + public double MaxHeight {{ get; set; }} + + public double Diameter {{ get; set; }} + public double MaxDiameter {{ get; set; }} +}} + +private void InitializeData() +{{ + if (BarItems == null) BarItems = new ObservableCollection(); + BarItems.Add(new Bar(300, this.MaxLength)); + BarItems.Add(new Bar(25, this.MaxLength)); + BarItems.Add(new Bar(175, this.MaxLength)); +}} +"; + + public string Example2Xaml => $@" + + + + + + + + + + + + + + + + + + {_repeater2_Layout.fIndent(4)} + + + + + +"; + public string Example2CS => $@" +// using: {ThemeManager.Link_GithubRepo}/blob/main/source/iNKORE.UI.WPF.Modern.Gallery/Common/ActivityFeedLayout.cs + +public Page() +{{ + repeater2.ItemsSource = Enumerable.Range(0, 500); +}} + +public class MyDataTemplateSelector : DataTemplateSelector +{{ + public DataTemplate Normal {{ get; set; }} + public DataTemplate Accent {{ get; set; }} + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + {{ + if ((int)item % 2 == 0) + {{ + return Normal; + }} + else + {{ + return Accent; + }} + }} +}} +"; + + public string Example3Xaml => $@" + + + + + + + + + + + + + + + + + + + + + +"; + public string Example3CS => $@" +public class StringOrIntTemplateSelector : DataTemplateSelector +{{ + // Define the (currently empty) data templates to return + // These will be ""filled-in"" in the XAML code. + public DataTemplate StringTemplate {{ get; set; }} + + public DataTemplate IntTemplate {{ get; set; }} + + public override DataTemplate SelectTemplate(object item, DependencyObject container) + {{ + // Return the correct data template based on the item's type. + if (item.GetType() == typeof(String)) return StringTemplate; + else if (item.GetType() == typeof(int)) return IntTemplate; + else return null; + }} +}} +"; + + public string Example4Xaml => $@" + + + + + + + + + + + + + + + + + + + + +"; + public string Example4CS => $@" +private void InitializeData() +{{ + List basicData = + [ + 64, + ""Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua."", + 128, + ""Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat."", + 256, + ""Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur."", + 512, + ""Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."", + 1024, + ]; + MixedTypeRepeater.ItemsSource = basicData; + + List nestedCategories = + [ + new NestedCategory(""Fruits"", new ObservableCollection + {{ + ""Apricots"", ""Bananas"", ""Grapes"", ""Strawberries"", + ""Watermelon"", ""Plums"", ""Blueberries"" + }}), + new NestedCategory(""Vegetables"", new ObservableCollection + {{ + ""Broccoli"", ""Spinach"", ""Sweet potato"", ""Cauliflower"", + ""Onion"", ""Brussel sprouts"", ""Carrots"" + }}), + new NestedCategory(""Grains"", new ObservableCollection + {{ + ""Rice"", ""Quinoa"", ""Pasta"", ""Bread"", + ""Farro"", ""Oats"", ""Barley"" + }}), + new NestedCategory(""Proteins"", new ObservableCollection + {{ + ""Steak"", ""Chicken"", ""Tofu"", ""Salmon"", + ""Pork"", ""Chickpeas"", ""Eggs"" + }}), + ]; + + outerRepeater.ItemsSource = nestedCategories; +}} +"; + + #endregion + + #region Other Pages + + private readonly string _thisDataContext_ = $@" +// using: {ThemeManager.Link_GithubRepo}/blob/main/source/iNKORE.UI.WPF.Modern.Gallery/Pages/Controls/Windows/ListViewPage.xaml.cs + +private async void OnLoaded(object sender, RoutedEventArgs e) +{{ + DataContext = await Contact.GetContactsAsync(); +}} +"; + + + public string Example5Xaml => $@" + + + + + + + + + + + + + + + + + + + + + + + + + + +"; + public string Example5CS => $@" +{_thisDataContext_} +"; + + public string Example6Xaml => $@" + + + + + + + + + + + + +"; + public string Example6CS => $@" +{_thisDataContext_} +"; + + public string Example7Xaml => $@" + + + + + + + + + + + + +"; + public string Example7CS => $@" +{_thisDataContext_} +"; + + #endregion + #endregion } @@ -231,7 +716,6 @@ public NestedCategory(string catName, ObservableCollection catItems) } } - public class MyDataTemplateSelector : DataTemplateSelector { public DataTemplate Normal { get; set; } @@ -239,14 +723,8 @@ public class MyDataTemplateSelector : DataTemplateSelector public override DataTemplate SelectTemplate(object item, DependencyObject container) { - if ((int)item % 2 == 0) - { - return Normal; - } - else - { - return Accent; - } + if ((int)item % 2 == 0) return Normal; + else return Accent; } } @@ -261,18 +739,9 @@ public class StringOrIntTemplateSelector : DataTemplateSelector public override DataTemplate SelectTemplate(object item, DependencyObject container) { // Return the correct data template based on the item's type. - if (item.GetType() == typeof(String)) - { - return StringTemplate; - } - else if (item.GetType() == typeof(int)) - { - return IntTemplate; - } - else - { - return null; - } + if (item.GetType() == typeof(String)) return StringTemplate; + else if (item.GetType() == typeof(int)) return IntTemplate; + else return null; } }