Repository: sourcechord/GridExtra Branch: master Commit: 0e516468b8bb Files: 44 Total size: 148.0 KB Directory structure: gitextract_enuf11w3/ ├── .gitignore ├── GridExtra.Shared/ │ ├── BreakPoints.cs │ ├── GridEx.cs │ ├── GridExtra.Shared.projitems │ ├── GridExtra.Shared.shproj │ ├── ResponsiveGrid.Properties.cs │ └── ResponsiveGrid.cs ├── GridExtra.Uwp/ │ ├── GridExtra.Uwp.csproj │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ └── GridExtra.Uwp.rd.xml │ └── project.json ├── GridExtra.Wpf/ │ ├── BreakPointsTypeConverter.cs │ ├── GridExtra.Wpf.csproj │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ ├── Resources.Designer.cs │ │ ├── Resources.resx │ │ ├── Settings.Designer.cs │ │ └── Settings.settings │ └── WrapPanelEx.cs ├── GridExtra.sln ├── LICENSE ├── Nuget/ │ ├── GridExtra.nuspec │ └── pack.bat ├── README.md └── Sample/ ├── BasicSample.Uwp/ │ ├── App.xaml │ ├── App.xaml.cs │ ├── BasicSample.Uwp.csproj │ ├── MainPage.xaml │ ├── MainPage.xaml.cs │ ├── Package.appxmanifest │ ├── Properties/ │ │ ├── AssemblyInfo.cs │ │ └── Default.rd.xml │ └── project.json └── BasicSample.Wpf/ ├── App.config ├── App.xaml ├── App.xaml.cs ├── BasicSample.Wpf.csproj ├── MainWindow.xaml ├── MainWindow.xaml.cs └── Properties/ ├── AssemblyInfo.cs ├── Resources.Designer.cs ├── Resources.resx ├── Settings.Designer.cs └── Settings.settings ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. # User-specific files *.suo *.user *.userosscache *.sln.docstates # User-specific files (MonoDevelop/Xamarin Studio) *.userprefs # Build results [Dd]ebug/ [Dd]ebugPublic/ [Rr]elease/ [Rr]eleases/ x64/ x86/ bld/ [Bb]in/ [Oo]bj/ [Ll]og/ # Visual Studio 2015 cache/options directory .vs/ # Uncomment if you have tasks that create the project's static files in wwwroot #wwwroot/ # MSTest test Results [Tt]est[Rr]esult*/ [Bb]uild[Ll]og.* # NUNIT *.VisualState.xml TestResult.xml # Build Results of an ATL Project [Dd]ebugPS/ [Rr]eleasePS/ dlldata.c # DNX project.lock.json artifacts/ *_i.c *_p.c *_i.h *.ilk *.meta *.obj *.pch *.pdb *.pgc *.pgd *.rsp *.sbr *.tlb *.tli *.tlh *.tmp *.tmp_proj *.log *.vspscc *.vssscc .builds *.pidb *.svclog *.scc # Chutzpah Test files _Chutzpah* # Visual C++ cache files ipch/ *.aps *.ncb *.opendb *.opensdf *.sdf *.cachefile *.VC.db *.VC.VC.opendb # Visual Studio profiler *.psess *.vsp *.vspx *.sap # TFS 2012 Local Workspace $tf/ # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in _ReSharper*/ *.[Rr]e[Ss]harper *.DotSettings.user # JustCode is a .NET coding add-in .JustCode # TeamCity is a build add-in _TeamCity* # DotCover is a Code Coverage Tool *.dotCover # NCrunch _NCrunch_* .*crunch*.local.xml nCrunchTemp_* # MightyMoose *.mm.* AutoTest.Net/ # Web workbench (sass) .sass-cache/ # Installshield output folder [Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ DocProject/Help/*.HxT DocProject/Help/*.HxC DocProject/Help/*.hhc DocProject/Help/*.hhk DocProject/Help/*.hhp DocProject/Help/Html2 DocProject/Help/html # Click-Once directory publish/ # Publish Web Output *.[Pp]ublish.xml *.azurePubxml # TODO: Comment the next line if you want to checkin your web deploy settings # but database connection strings (with potential passwords) will be unencrypted *.pubxml *.publishproj # Microsoft Azure Web App publish settings. Comment the next line if you want to # checkin your Azure Web App publish settings, but sensitive information contained # in these scripts will be unencrypted PublishScripts/ # NuGet Packages *.nupkg # The packages folder can be ignored because of Package Restore **/packages/* # except build/, which is used as an MSBuild target. !**/packages/build/ # Uncomment if necessary however generally it will be regenerated when needed #!**/packages/repositories.config # NuGet v3's project.json files produces more ignoreable files *.nuget.props *.nuget.targets # Microsoft Azure Build Output csx/ *.build.csdef # Microsoft Azure Emulator ecf/ rcf/ # Windows Store app package directories and files AppPackages/ BundleArtifacts/ Package.StoreAssociation.xml _pkginfo.txt # Visual Studio cache files # files ending in .cache can be ignored *.[Cc]ache # but keep track of directories ending in .cache !*.[Cc]ache/ # Others ClientBin/ ~$* *~ *.dbmdl *.dbproj.schemaview *.pfx *.publishsettings node_modules/ orleans.codegen.cs # Since there are multiple workflows, uncomment next line to ignore bower_components # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) #bower_components/ # RIA/Silverlight projects Generated_Code/ # Backup & report files from converting an old project file # to a newer Visual Studio version. Backup files are not needed, # because we have git ;-) _UpgradeReport_Files/ Backup*/ UpgradeLog*.XML UpgradeLog*.htm # SQL Server files *.mdf *.ldf # Business Intelligence projects *.rdl.data *.bim.layout *.bim_*.settings # Microsoft Fakes FakesAssemblies/ # GhostDoc plugin setting file *.GhostDoc.xml # Node.js Tools for Visual Studio .ntvs_analysis.dat # Visual Studio 6 build log *.plg # Visual Studio 6 workspace options file *.opt # Visual Studio LightSwitch build output **/*.HTMLClient/GeneratedArtifacts **/*.DesktopClient/GeneratedArtifacts **/*.DesktopClient/ModelManifest.xml **/*.Server/GeneratedArtifacts **/*.Server/ModelManifest.xml _Pvt_Extensions # Paket dependency manager .paket/paket.exe paket-files/ # FAKE - F# Make .fake/ # JetBrains Rider .idea/ *.sln.iml ================================================ FILE: GridExtra.Shared/BreakPoints.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; #if WINDOWS_WPF using System.Windows; using System.Windows.Controls; using System.ComponentModel; #elif WINDOWS_UWP using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else #endif namespace SourceChord.GridExtra { #if WINDOWS_WPF [TypeConverter(typeof(BreakPointsTypeConverter))] #endif public class BreakPoints : DependencyObject { public double XS_SM { get { return (double)GetValue(XS_SMProperty); } set { SetValue(XS_SMProperty, value); } } // Using a DependencyProperty as the backing store for XS_SM. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_SMProperty = DependencyProperty.Register("XS_SM", typeof(double), typeof(BreakPoints), new PropertyMetadata(768.0)); public double SM_MD { get { return (double)GetValue(SM_MDProperty); } set { SetValue(SM_MDProperty, value); } } // Using a DependencyProperty as the backing store for SM_MD. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_MDProperty = DependencyProperty.Register("SM_MD", typeof(double), typeof(BreakPoints), new PropertyMetadata(992.0)); public double MD_LG { get { return (double)GetValue(MD_LGProperty); } set { SetValue(MD_LGProperty, value); } } // Using a DependencyProperty as the backing store for MD_LG. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_LGProperty = DependencyProperty.Register("MD_LG", typeof(double), typeof(BreakPoints), new PropertyMetadata(1200.0)); public BreakPoints() { } } } ================================================ FILE: GridExtra.Shared/GridEx.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; #if WINDOWS_WPF using System.Windows; using System.Windows.Controls; using System.Windows.Media; #elif WINDOWS_UWP using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else #endif namespace SourceChord.GridExtra { #if WINDOWS_WPF using LayoutUpdateEventHandler = EventHandler; #elif WINDOWS_UWP using LayoutUpdateEventHandler = EventHandler; #else #endif public class AreaDefinition { public int Row { get; set; } public int Column { get; set; } public int RowSpan { get; set; } public int ColumnSpan { get; set; } public AreaDefinition(int row, int column, int rowSpan, int columnSpan) { this.Row = row; this.Column = column; this.RowSpan = rowSpan; this.ColumnSpan = columnSpan; } } public class NamedAreaDefinition : AreaDefinition { public string Name { get; set; } public NamedAreaDefinition(string name, int row, int column, int rowSpan, int columnSpan) : base(row, column, rowSpan, columnSpan) { this.Name = name; } } struct GridLengthDefinition { public GridLength GridLength; public double? Min; public double? Max; } public static class GridEx { public static Orientation GetAutoFillOrientation(DependencyObject obj) { return (Orientation)obj.GetValue(AutoFillOrientationProperty); } public static void SetAutoFillOrientation(DependencyObject obj, Orientation value) { obj.SetValue(AutoFillOrientationProperty, value); } // Using a DependencyProperty as the backing store for AutoFillOrientation. This enables animation, styling, binding, etc... public static readonly DependencyProperty AutoFillOrientationProperty = DependencyProperty.RegisterAttached("AutoFillOrientation", typeof(Orientation), typeof(GridEx), new PropertyMetadata(Orientation.Horizontal)); public static bool GetAutoFillChildren(DependencyObject obj) { return (bool)obj.GetValue(AutoFillChildrenProperty); } public static void SetAutoFillChildren(DependencyObject obj, bool value) { obj.SetValue(AutoFillChildrenProperty, value); } // Using a DependencyProperty as the backing store for AutoFillChildren. This enables animation, styling, binding, etc... public static readonly DependencyProperty AutoFillChildrenProperty = DependencyProperty.RegisterAttached("AutoFillChildren", typeof(bool), typeof(GridEx), new PropertyMetadata(false, OnAutoFillChildrenChanged)); private static void OnAutoFillChildrenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = d as Grid; var isEnabled = (bool)e.NewValue; if (grid == null) { return; } if (isEnabled) { var layoutUpdateCallback = CreateLayoutUpdateHandler(grid); // イベントの登録 grid.LayoutUpdated += layoutUpdateCallback; SetLayoutUpdatedCallback(grid, layoutUpdateCallback); // AutoFill処理を行う AutoFill(grid); } else { // イベントの解除 var callback = GetLayoutUpdatedCallback(grid); grid.LayoutUpdated -= callback; // AutoFill処理のリセット ClearAutoFill(grid); } } private static LayoutUpdateEventHandler CreateLayoutUpdateHandler(Grid grid) { var prevCount = 0; var prevColumn = grid.ColumnDefinitions.Count; var prevRow = grid.RowDefinitions.Count; var prevOrientation = GetAutoFillOrientation(grid); var layoutUpdateCallback = new LayoutUpdateEventHandler((sender, args) => { var count = grid.Children.Count; var column = grid.ColumnDefinitions.Count; var row = grid.RowDefinitions.Count; var orientation = GetAutoFillOrientation(grid); if (count != prevCount || column != prevColumn || row != prevRow || orientation != prevOrientation) { AutoFill(grid); prevCount = count; prevColumn = column; prevRow = row; prevOrientation = orientation; } }); return layoutUpdateCallback; } public static LayoutUpdateEventHandler GetLayoutUpdatedCallback(DependencyObject obj) { return (LayoutUpdateEventHandler)obj.GetValue(LayoutUpdatedCallbackProperty); } private static void SetLayoutUpdatedCallback(DependencyObject obj, LayoutUpdateEventHandler value) { obj.SetValue(LayoutUpdatedCallbackProperty, value); } // Using a DependencyProperty as the backing store for LayoutUpdatedCallback. This enables animation, styling, binding, etc... public static readonly DependencyProperty LayoutUpdatedCallbackProperty = DependencyProperty.RegisterAttached("LayoutUpdatedCallback", typeof(LayoutUpdateEventHandler), typeof(GridEx), new PropertyMetadata(null)); private static void AutoFill(Grid grid) { var isEnabled = GetAutoFillChildren(grid); var rowCount = grid.RowDefinitions.Count; var columnCount = grid.ColumnDefinitions.Count; var orientation = GetAutoFillOrientation(grid); if (!isEnabled || rowCount == 0 || columnCount == 0) return; var area = new bool[rowCount, columnCount]; var autoLayoutList = new List(); // Grid内の位置固定要素のチェック foreach (FrameworkElement child in grid.Children) { // AreaName ⇒ Areaの優先順位で、グリッド位置の設定を行う var region = GetAreaNameRegion(child) ?? GetAreaRegion(child); var isFixed = region != null; if (isFixed) { // 位置指定されているので、AutoFillReservedAreaに記録する var row = region.Row; var column = region.Column; var rowSpan = region.RowSpan; var columnSpan = region.ColumnSpan; for (var i = row; i < row + rowSpan; i++) for (var j = column; j < column + columnSpan; j++) { if (columnCount <= j || rowCount <= i) { continue; } area[i, j] = true; } } else { // Gridの位置未設定の要素は、自動レイアウト対象としてリストに追加 autoLayoutList.Add(child); } } var count = 0; var numOfCell = rowCount * columnCount; var isHorizontal = orientation == Orientation.Horizontal; var isOverflow = false; // Gridの子要素を、順番にGrid内に並べていく foreach (FrameworkElement child in autoLayoutList) { // Visibility.Collapsedの項目は除外する if (child.Visibility == Visibility.Collapsed) { continue; } while (true) { var x = isHorizontal ? count % columnCount : count / rowCount; var y = isHorizontal ? count / columnCount : count % rowCount; var canArrange = isOverflow ? true : !area[y, x]; if (canArrange) { Grid.SetRow(child, y); Grid.SetColumn(child, x); Grid.SetRowSpan(child, 1); Grid.SetColumnSpan(child, 1); } if (count + 1 < numOfCell) { count++; } else { isOverflow = true; } if (canArrange) { break; } } } } private static void ClearAutoFill(Grid grid) { foreach (FrameworkElement child in grid.Children) { child.ClearValue(Grid.RowProperty); child.ClearValue(Grid.ColumnProperty); child.ClearValue(Grid.RowSpanProperty); child.ClearValue(Grid.ColumnSpanProperty); UpdateItemPosition(child); } } public static string GetColumnDefinition(DependencyObject obj) { return (string)obj.GetValue(ColumnDefinitionProperty); } public static void SetColumnDefinition(DependencyObject obj, string value) { obj.SetValue(ColumnDefinitionProperty, value); } // Using a DependencyProperty as the backing store for ColumnDefinition. This enables animation, styling, binding, etc... public static readonly DependencyProperty ColumnDefinitionProperty = DependencyProperty.RegisterAttached("ColumnDefinition", typeof(string), typeof(GridEx), new PropertyMetadata(null, OnColumnDefinitionChanged)); private static void OnColumnDefinitionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = d as Grid; var param = e.NewValue as string; InitializeColumnDefinition(grid, param); var template = GetTemplateArea(grid); if (template != null) { InitializeTemplateArea(grid, template); } } private static void InitializeColumnDefinition(Grid grid, string param) { if (grid == null || param == null) { return; } grid.ColumnDefinitions.Clear(); var list = param.Split(',') .Select(o => o.Trim()); foreach (var item in list) { var def = StringToGridLengthDefinition(item); var columnDefinition = new ColumnDefinition() { Width = def.GridLength }; if (def.Max != null) { columnDefinition.MaxWidth = def.Max.Value; } if (def.Min != null) { columnDefinition.MinWidth = def.Min.Value; } grid.ColumnDefinitions.Add(columnDefinition); } } public static string GetRowDefinition(DependencyObject obj) { return (string)obj.GetValue(RowDefinitionProperty); } public static void SetRowDefinition(DependencyObject obj, string value) { obj.SetValue(RowDefinitionProperty, value); } // Using a DependencyProperty as the backing store for RowDefinition. This enables animation, styling, binding, etc... public static readonly DependencyProperty RowDefinitionProperty = DependencyProperty.RegisterAttached("RowDefinition", typeof(string), typeof(GridEx), new PropertyMetadata(null, OnRowDefinitionChanged)); private static void OnRowDefinitionChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = d as Grid; var param = e.NewValue as string; InitializeRowDefinition(grid, param); var template = GetTemplateArea(grid); if (template != null) { InitializeTemplateArea(grid, template); } } private static void InitializeRowDefinition(Grid grid, string param) { if (grid == null || param == null) { return; } grid.RowDefinitions.Clear(); var list = param.Split(',') .Select(o => o.Trim()); foreach (var item in list) { var def = StringToGridLengthDefinition(item); var rowDefinition = new RowDefinition() { Height = def.GridLength }; if (def.Max != null) { rowDefinition.MaxHeight = def.Max.Value; } if (def.Min != null) { rowDefinition.MinHeight = def.Min.Value; } grid.RowDefinitions.Add(rowDefinition); } } // ↓GridEx内部でだけ使用する、プライベートな添付プロパティ public static IList GetAreaDefinitions(DependencyObject obj) { return (IList)obj.GetValue(AreaDefinitionsProperty); } private static void SetAreaDefinitions(DependencyObject obj, IList value) { obj.SetValue(AreaDefinitionsProperty, value); } // Using a DependencyProperty as the backing store for AreaDefinitions. This enables animation, styling, binding, etc... public static readonly DependencyProperty AreaDefinitionsProperty = DependencyProperty.RegisterAttached("AreaDefinitions", typeof(IList), typeof(GridEx), new PropertyMetadata(null)); public static string GetTemplateArea(DependencyObject obj) { return (string)obj.GetValue(TemplateAreaProperty); } public static void SetTemplateArea(DependencyObject obj, string value) { obj.SetValue(TemplateAreaProperty, value); } // Using a DependencyProperty as the backing store for TemplateArea. This enables animation, styling, binding, etc... public static readonly DependencyProperty TemplateAreaProperty = DependencyProperty.RegisterAttached("TemplateArea", typeof(string), typeof(GridEx), new PropertyMetadata(null, OnTemplateAreaChanged)); private static void OnTemplateAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var grid = d as Grid; var param = e.NewValue as string; if (d == null) { return; } // グリッドを一度初期化 grid.RowDefinitions.Clear(); grid.ColumnDefinitions.Clear(); // GridEx.RowDefinition/GridEx.ColumnDefinitionの設定内容で、行/列を初期化 InitializeRowDefinition(grid, GetRowDefinition(grid)); InitializeColumnDefinition(grid, GetColumnDefinition(grid)); if (param != null) { InitializeTemplateArea(grid, param); } } private static void InitializeTemplateArea(Grid grid, string param) { // 行×列数のチェック // 空行や、スペースを除去して、行×列のデータ構造に変形 var columns = param.Split(new[] { '\n', '/' }) .Select(o => o.Trim()) .Where(o => !string.IsNullOrWhiteSpace(o)) .Select(o => o.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries)); // 行×列数のチェック var num = columns.FirstOrDefault().Count(); var isValidRowColumn = columns.All(o => o.Count() == num); if (!isValidRowColumn) { // Invalid Row Columns... throw new ArgumentException("Invalid Row/Column definition."); } // グリッド数を調整(不足分の行/列を足す) var rowShortage = columns.Count() - grid.RowDefinitions.Count; for (var i = 0; i < rowShortage; i++) { grid.RowDefinitions.Add(new RowDefinition()); } var columnShortage = num - grid.ColumnDefinitions.Count; for (var i = 0; i < columnShortage; i++) { grid.ColumnDefinitions.Add(new ColumnDefinition()); } // Area定義をパース var areaList = ParseAreaDefinition(columns); SetAreaDefinitions(grid, areaList); // 全体レイアウトの定義が変わったので、 // Gridの子要素のすべてのRegion設定を反映しなおす foreach (FrameworkElement child in grid.Children) { UpdateItemPosition(child); } } private static IList ParseAreaDefinition(IEnumerable columns) { var result = new List(); // Regionが正しく連結されているかチェック var flatten = columns.SelectMany( (item, index) => item.Select((o, xIndex) => new { row = index, column = xIndex, name = o }) ); var groups = flatten.GroupBy(o => o.name); foreach (var group in groups) { var left = group.Min(o => o.column); var top = group.Min(o => o.row); var right = group.Max(o => o.column); var bottom = group.Max(o => o.row); var isValid = true; for (var y = top; y <= bottom; y++) for (var x = left; x <= right; x++) { isValid = isValid && group.Any(o => o.column == x && o.row == y); } if (!isValid) { throw new ArgumentException($"\"{group.Key}\" is invalid area definition."); } result.Add(new NamedAreaDefinition(group.Key, top, left, bottom - top + 1, right - left + 1)); } return result; } private static GridLengthDefinition StringToGridLengthDefinition(string source) { var r = new System.Text.RegularExpressions.Regex(@"(^[^\(\)]+)(?:\((.*)-(.*)\))?"); var m = r.Match(source); var length = m.Groups[1].Value; var min = m.Groups[2].Value; var max = m.Groups[3].Value; double temp; var result = new GridLengthDefinition() { GridLength = StringToGridLength(length), Min = double.TryParse(min, out temp) ? temp : (double?)null, Max = double.TryParse(max, out temp) ? temp : (double?)null }; return result; } #if WINDOWS_WPF private static GridLength StringToGridLength(string source) { var glc = TypeDescriptor.GetConverter(typeof(GridLength)); return (GridLength)glc.ConvertFromString(source); } #elif WINDOWS_UWP private static GridLength StringToGridLength(string source) { GridLength gridLength; if (source.ToLower() == "auto") { gridLength = new GridLength(0.0, GridUnitType.Auto); } else { var r = new System.Text.RegularExpressions.Regex(@"([\d\.]*)(\*?)"); var m = r.Match(source); var val = m.Groups[1].Value; var unit = m.Groups[2].Value; double size; var isValid = double.TryParse(val, out size); if (unit == "*") { if (string.IsNullOrEmpty(val)) { gridLength = new GridLength(1, GridUnitType.Star); } else { if (!isValid) { throw new ArgumentException(); } gridLength = new GridLength(size, GridUnitType.Star); } } else if (string.IsNullOrEmpty(unit)) { if (!isValid) { throw new ArgumentException(); ; } gridLength = new GridLength(size, GridUnitType.Pixel); } else { // 変換失敗 throw new ArgumentException(); } } return gridLength; } #else #endif //===================================================================== // Grid内の子要素に適用するための添付プロパティ類 //===================================================================== public static string GetAreaName(DependencyObject obj) { return (string)obj.GetValue(AreaNameProperty); } public static void SetAreaName(DependencyObject obj, string value) { obj.SetValue(AreaNameProperty, value); } // Using a DependencyProperty as the backing store for AreaName. This enables animation, styling, binding, etc... public static readonly DependencyProperty AreaNameProperty = DependencyProperty.RegisterAttached("AreaName", typeof(string), typeof(GridEx), new PropertyMetadata(null, OnAreaNameChanged)); private static void OnAreaNameChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctrl = d as FrameworkElement; if (ctrl == null) { return; } UpdateItemPosition(ctrl); // 子要素全体のAutoFillを計算しなおす var grid = ctrl.Parent as Grid; var isAutoFill = GetAutoFillChildren(grid); if (isAutoFill) { AutoFill(grid); } } public static string GetArea(DependencyObject obj) { return (string)obj.GetValue(AreaProperty); } public static void SetArea(DependencyObject obj, string value) { obj.SetValue(AreaProperty, value); } // Using a DependencyProperty as the backing store for Area. This enables animation, styling, binding, etc... public static readonly DependencyProperty AreaProperty = DependencyProperty.RegisterAttached("Area", typeof(string), typeof(GridEx), new PropertyMetadata(null, OnAreaChanged)); private static void OnAreaChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var ctrl = d as FrameworkElement; if (d == null) { return; } UpdateItemPosition(ctrl); // 子要素全体のAutoFillを計算しなおす var grid = ctrl.Parent as Grid; if (grid == null) { return; } var isAutoFill = GetAutoFillChildren(grid); if (isAutoFill) { AutoFill(grid); } } private static void UpdateItemPosition(FrameworkElement element) { // AreaName ⇒ Areaの優先順位で、グリッド位置の設定を行う var area = GetAreaNameRegion(element) ?? GetAreaRegion(element); if (area != null) { Grid.SetRow(element, area.Row); Grid.SetColumn(element, area.Column); Grid.SetRowSpan(element, area.RowSpan); Grid.SetColumnSpan(element, area.ColumnSpan); } } private static AreaDefinition GetAreaNameRegion(FrameworkElement element) { var name = GetAreaName(element); var grid = element.Parent as Grid; if (grid == null || name == null) { return null; } var areaList = GetAreaDefinitions(grid); if (areaList == null) { return null; } var area = areaList.FirstOrDefault(o => o.Name == name); if (area == null) { return null; } return new AreaDefinition(area.Row, area.Column, area.RowSpan, area.ColumnSpan); } private static AreaDefinition GetAreaRegion(FrameworkElement element) { var param = GetArea(element); if (param == null) { return null; } var list = param.Split(',') .Select(o => o.Trim()) .Select(o => int.Parse(o)) .ToList(); // Row, Column, RowSpan, ColumnSpan if (list.Count() != 4) { return null; } return new AreaDefinition(list[0], list[1], list[2], list[3]); } } } ================================================ FILE: GridExtra.Shared/GridExtra.Shared.projitems ================================================  $(MSBuildAllProjects);$(MSBuildThisFileFullPath) true 4914d867-f667-4151-a039-3fde665f3106 SourceChord.GridExtra ================================================ FILE: GridExtra.Shared/GridExtra.Shared.shproj ================================================  4914d867-f667-4151-a039-3fde665f3106 14.0 ================================================ FILE: GridExtra.Shared/ResponsiveGrid.Properties.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; #if WINDOWS_WPF using System.Windows; using System.Windows.Controls; #elif WINDOWS_UWP using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else #endif namespace SourceChord.GridExtra { public partial class ResponsiveGrid { #region ResponsiveGrid自体に設定する依存関係プロパティ // 各種ブレークポイントの設定用プロパティ public int MaxDivision { get { return (int)GetValue(MaxDivisionProperty); } set { SetValue(MaxDivisionProperty, value); } } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for MaxDivision. This enables animation, styling, binding, etc... public static readonly DependencyProperty MaxDivisionProperty = DependencyProperty.Register("MaxDivision", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(12, FrameworkPropertyMetadataOptions.AffectsMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for MaxDivision. This enables animation, styling, binding, etc... public static readonly DependencyProperty MaxDivisionProperty = DependencyProperty.Register("MaxDivision", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(12, OnDependencyPropertyChanged)); private static void OnDependencyPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var element = d as FrameworkElement; var parent = element?.Parent as ResponsiveGrid; parent?.InvalidateMeasure(); } #else #endif public BreakPoints BreakPoints { get { return (BreakPoints)GetValue(BreakPointsProperty); } set { SetValue(BreakPointsProperty, value); } } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for BreakPoints. This enables animation, styling, binding, etc... public static readonly DependencyProperty BreakPointsProperty = DependencyProperty.Register("BreakPoints", typeof(BreakPoints), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for BreakPoints. This enables animation, styling, binding, etc... public static readonly DependencyProperty BreakPointsProperty = DependencyProperty.Register("BreakPoints", typeof(BreakPoints), typeof(ResponsiveGrid), new PropertyMetadata(null, OnDependencyPropertyChanged)); #else #endif #if WINDOWS_WPF public bool ShowGridLines { get { return (bool)GetValue(ShowGridLinesProperty); } set { SetValue(ShowGridLinesProperty, value); } } // Using a DependencyProperty as the backing store for ShowGridLines. This enables animation, styling, binding, etc... public static readonly DependencyProperty ShowGridLinesProperty = DependencyProperty.Register("ShowGridLines", typeof(bool), typeof(ResponsiveGrid), new PropertyMetadata(false)); #endif #endregion #region 各子要素のサイズを決めるための添付プロパティ public static int GetXS(DependencyObject obj) { return (int)obj.GetValue(XSProperty); } public static void SetXS(DependencyObject obj, int value) { obj.SetValue(XSProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for XS. This enables animation, styling, binding, etc... public static readonly DependencyProperty XSProperty = DependencyProperty.RegisterAttached("XS", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for XS. This enables animation, styling, binding, etc... public static readonly DependencyProperty XSProperty = DependencyProperty.RegisterAttached("XS", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); private static void OnAttachedPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var element = d as FrameworkElement; var parent = element?.Parent as ResponsiveGrid; parent?.InvalidateMeasure(); } #else #endif public static int GetSM(DependencyObject obj) { return (int)obj.GetValue(SMProperty); } public static void SetSM(DependencyObject obj, int value) { obj.SetValue(SMProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for SM. This enables animation, styling, binding, etc... public static readonly DependencyProperty SMProperty = DependencyProperty.RegisterAttached("SM", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for SM. This enables animation, styling, binding, etc... public static readonly DependencyProperty SMProperty = DependencyProperty.RegisterAttached("SM", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetMD(DependencyObject obj) { return (int)obj.GetValue(MDProperty); } public static void SetMD(DependencyObject obj, int value) { obj.SetValue(MDProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for MD. This enables animation, styling, binding, etc... public static readonly DependencyProperty MDProperty = DependencyProperty.RegisterAttached("MD", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for MD. This enables animation, styling, binding, etc... public static readonly DependencyProperty MDProperty = DependencyProperty.RegisterAttached("MD", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetLG(DependencyObject obj) { return (int)obj.GetValue(LGProperty); } public static void SetLG(DependencyObject obj, int value) { obj.SetValue(LGProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for LG. This enables animation, styling, binding, etc... public static readonly DependencyProperty LGProperty = DependencyProperty.RegisterAttached("LG", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for LG. This enables animation, styling, binding, etc... public static readonly DependencyProperty LGProperty = DependencyProperty.RegisterAttached("LG", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif #endregion #region Offsetプロパティ public static int GetXS_Offset(DependencyObject obj) { return (int)obj.GetValue(XS_OffsetProperty); } public static void SetXS_Offset(DependencyObject obj, int value) { obj.SetValue(XS_OffsetProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for XS_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_OffsetProperty = DependencyProperty.RegisterAttached("XS_Offset", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for XS_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_OffsetProperty = DependencyProperty.RegisterAttached("XS_Offset", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetSM_Offset(DependencyObject obj) { return (int)obj.GetValue(SM_OffsetProperty); } public static void SetSM_Offset(DependencyObject obj, int value) { obj.SetValue(SM_OffsetProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for SM_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_OffsetProperty = DependencyProperty.RegisterAttached("SM_Offset", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for SM_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_OffsetProperty = DependencyProperty.RegisterAttached("SM_Offset", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetMD_Offset(DependencyObject obj) { return (int)obj.GetValue(MD_OffsetProperty); } public static void SetMD_Offset(DependencyObject obj, int value) { obj.SetValue(MD_OffsetProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for MD_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_OffsetProperty = DependencyProperty.RegisterAttached("MD_Offset", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for MD_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_OffsetProperty = DependencyProperty.RegisterAttached("MD_Offset", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetLG_Offset(DependencyObject obj) { return (int)obj.GetValue(LG_OffsetProperty); } public static void SetLG_Offset(DependencyObject obj, int value) { obj.SetValue(LG_OffsetProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for LG_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_OffsetProperty = DependencyProperty.RegisterAttached("LG_Offset", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for LG_Offset. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_OffsetProperty = DependencyProperty.RegisterAttached("LG_Offset", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif #endregion #region Pushプロパティ public static int GetXS_Push(DependencyObject obj) { return (int)obj.GetValue(XS_PushProperty); } public static void SetXS_Push(DependencyObject obj, int value) { obj.SetValue(XS_PushProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for XS_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_PushProperty = DependencyProperty.RegisterAttached("XS_Push", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for XS_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_PushProperty = DependencyProperty.RegisterAttached("XS_Push", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetSM_Push(DependencyObject obj) { return (int)obj.GetValue(SM_PushProperty); } public static void SetSM_Push(DependencyObject obj, int value) { obj.SetValue(SM_PushProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for SM_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_PushProperty = DependencyProperty.RegisterAttached("SM_Push", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for SM_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_PushProperty = DependencyProperty.RegisterAttached("SM_Push", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetMD_Push(DependencyObject obj) { return (int)obj.GetValue(MD_PushProperty); } public static void SetMD_Push(DependencyObject obj, int value) { obj.SetValue(MD_PushProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for MD_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_PushProperty = DependencyProperty.RegisterAttached("MD_Push", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for MD_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_PushProperty = DependencyProperty.RegisterAttached("MD_Push", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetLG_Push(DependencyObject obj) { return (int)obj.GetValue(LG_PushProperty); } public static void SetLG_Push(DependencyObject obj, int value) { obj.SetValue(LG_PushProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for LG_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_PushProperty = DependencyProperty.RegisterAttached("LG_Push", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for LG_Push. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_PushProperty = DependencyProperty.RegisterAttached("LG_Push", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif #endregion #region Pullプロパティ public static int GetXS_Pull(DependencyObject obj) { return (int)obj.GetValue(XS_PullProperty); } public static void SetXS_Pull(DependencyObject obj, int value) { obj.SetValue(XS_PullProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for XS_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_PullProperty = DependencyProperty.RegisterAttached("XS_Pull", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for XS_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty XS_PullProperty = DependencyProperty.RegisterAttached("XS_Pull", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetSM_Pull(DependencyObject obj) { return (int)obj.GetValue(SM_PullProperty); } public static void SetSM_Pull(DependencyObject obj, int value) { obj.SetValue(SM_PullProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for SM_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_PullProperty = DependencyProperty.RegisterAttached("SM_Pull", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for SM_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty SM_PullProperty = DependencyProperty.RegisterAttached("SM_Pull", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetMD_Pull(DependencyObject obj) { return (int)obj.GetValue(MD_PullProperty); } public static void SetMD_Pull(DependencyObject obj, int value) { obj.SetValue(MD_PullProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for MD_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_PullProperty = DependencyProperty.RegisterAttached("MD_Pull", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for MD_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty MD_PullProperty = DependencyProperty.RegisterAttached("MD_Pull", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif public static int GetLG_Pull(DependencyObject obj) { return (int)obj.GetValue(LG_PullProperty); } public static void SetLG_Pull(DependencyObject obj, int value) { obj.SetValue(LG_PullProperty, value); } #if WINDOWS_WPF // Using a DependencyProperty as the backing store for LG_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_PullProperty = DependencyProperty.RegisterAttached("LG_Pull", typeof(int), typeof(ResponsiveGrid), new FrameworkPropertyMetadata(0, FrameworkPropertyMetadataOptions.AffectsParentMeasure)); #elif WINDOWS_UWP // Using a DependencyProperty as the backing store for LG_Pull. This enables animation, styling, binding, etc... public static readonly DependencyProperty LG_PullProperty = DependencyProperty.RegisterAttached("LG_Pull", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0, OnAttachedPropertyChanged)); #else #endif #endregion #region 読み取り専用の添付プロパティ public static int GetActualColumn(DependencyObject obj) { return (int)obj.GetValue(ActualColumnProperty); } protected static void SetActualColumn(DependencyObject obj, int value) { obj.SetValue(ActualColumnProperty, value); } // Using a DependencyProperty as the backing store for ActualColumn. This enables animation, styling, binding, etc... public static readonly DependencyProperty ActualColumnProperty = DependencyProperty.RegisterAttached("ActualColumn", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0)); public static int GetActualRow(DependencyObject obj) { return (int)obj.GetValue(ActualRowProperty); } protected static void SetActualRow(DependencyObject obj, int value) { obj.SetValue(ActualRowProperty, value); } // Using a DependencyProperty as the backing store for ActualRow. This enables animation, styling, binding, etc... public static readonly DependencyProperty ActualRowProperty = DependencyProperty.RegisterAttached("ActualRow", typeof(int), typeof(ResponsiveGrid), new PropertyMetadata(0)); #endregion } } ================================================ FILE: GridExtra.Shared/ResponsiveGrid.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; #if WINDOWS_WPF using System.Windows; using System.Windows.Controls; using System.Windows.Media; #elif WINDOWS_UWP using Windows.Foundation; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; #else #endif namespace SourceChord.GridExtra { public partial class ResponsiveGrid : Panel { public ResponsiveGrid() { this.MaxDivision = 12; this.BreakPoints = new BreakPoints(); } protected override Size MeasureOverride(Size availableSize) { var count = 0; var currentRow = 0; var availableWidth = double.IsPositiveInfinity(availableSize.Width) ? double.PositiveInfinity : availableSize.Width / this.MaxDivision; var children = this.Children.OfType(); foreach (UIElement child in this.Children) { if (child != null) { // Collapsedの時はレイアウトしない if (child.Visibility == Visibility.Collapsed) { continue; } var span = this.GetSpan(child, availableSize.Width); var offset = this.GetOffset(child, availableSize.Width); var push = this.GetPush(child, availableSize.Width); var pull = this.GetPull(child, availableSize.Width); if (count + span + offset > this.MaxDivision) { // リセット currentRow++; count = 0; } SetActualColumn(child, count + offset + push - pull); SetActualRow(child, currentRow); count += (span + offset); var size = new Size(availableWidth * span, double.PositiveInfinity); child.Measure(size); } } // 行ごとにグルーピングする var group = this.Children.OfType() .GroupBy(x => GetActualRow(x)); var totalSize = new Size(); if (group.Count() != 0) { totalSize.Width = group.Max(rows => rows.Sum(o => o.DesiredSize.Width)); totalSize.Height = group.Sum(rows => rows.Max(o => o.DesiredSize.Height)); } return totalSize; } protected int GetSpan(UIElement element, double width) { var span = 0; var getXS = new Func((o) => { var x = GetXS(o); return x != 0 ? x : this.MaxDivision; }); var getSM = new Func((o) => { var x = GetSM(o); return x != 0 ? x : getXS(o); }); var getMD = new Func((o) => { var x = GetMD(o); return x != 0 ? x : getSM(o); }); var getLG = new Func((o) => { var x = GetLG(o); return x != 0 ? x : getMD(o); }); if (width < this.BreakPoints.XS_SM) { span = getXS(element); } else if (width < this.BreakPoints.SM_MD) { span = getSM(element); } else if (width < this.BreakPoints.MD_LG) { span = getMD(element); } else { span = getLG(element); } return Math.Min(Math.Max(0, span), this.MaxDivision); ; } protected int GetOffset(UIElement element, double width) { var span = 0; var getXS = new Func((o) => { var x = GetXS_Offset(o); return x != 0 ? x : 0; }); var getSM = new Func((o) => { var x = GetSM_Offset(o); return x != 0 ? x : getXS(o); }); var getMD = new Func((o) => { var x = GetMD_Offset(o); return x != 0 ? x : getSM(o); }); var getLG = new Func((o) => { var x = GetLG_Offset(o); return x != 0 ? x : getMD(o); }); if (width < this.BreakPoints.XS_SM) { span = getXS(element); } else if (width < this.BreakPoints.SM_MD) { span = getSM(element); } else if (width < this.BreakPoints.MD_LG) { span = getMD(element); } else { span = getLG(element); } return Math.Min(Math.Max(0, span), this.MaxDivision); ; } protected int GetPush(UIElement element, double width) { var span = 0; var getXS = new Func((o) => { var x = GetXS_Push(o); return x != 0 ? x : 0; }); var getSM = new Func((o) => { var x = GetSM_Push(o); return x != 0 ? x : getXS(o); }); var getMD = new Func((o) => { var x = GetMD_Push(o); return x != 0 ? x : getSM(o); }); var getLG = new Func((o) => { var x = GetLG_Push(o); return x != 0 ? x : getMD(o); }); if (width < this.BreakPoints.XS_SM) { span = getXS(element); } else if (width < this.BreakPoints.SM_MD) { span = getSM(element); } else if (width < this.BreakPoints.MD_LG) { span = getMD(element); } else { span = getLG(element); } return Math.Min(Math.Max(0, span), this.MaxDivision); ; } protected int GetPull(UIElement element, double width) { var span = 0; var getXS = new Func((o) => { var x = GetXS_Pull(o); return x != 0 ? x : 0; }); var getSM = new Func((o) => { var x = GetSM_Pull(o); return x != 0 ? x : getXS(o); }); var getMD = new Func((o) => { var x = GetMD_Pull(o); return x != 0 ? x : getSM(o); }); var getLG = new Func((o) => { var x = GetLG_Pull(o); return x != 0 ? x : getMD(o); }); if (width < this.BreakPoints.XS_SM) { span = getXS(element); } else if (width < this.BreakPoints.SM_MD) { span = getSM(element); } else if (width < this.BreakPoints.MD_LG) { span = getMD(element); } else { span = getLG(element); } return Math.Min(Math.Max(0, span), this.MaxDivision); ; } protected override Size ArrangeOverride(Size finalSize) { var columnWidth = finalSize.Width / this.MaxDivision; // 行ごとにグルーピングする var group = this.Children.OfType() .GroupBy(x => GetActualRow(x)); double temp = 0; foreach (var rows in group) { double max = 0; var columnHeight = rows.Max(o => o.DesiredSize.Height); foreach (var element in rows) { var column = GetActualColumn(element); var row = GetActualRow(element); var columnSpan = this.GetSpan(element, finalSize.Width); var rect = new Rect(columnWidth * column, temp, columnWidth * columnSpan, columnHeight); element.Arrange(rect); max = Math.Max(element.DesiredSize.Height, max); } temp += max; } return base.ArrangeOverride(finalSize); } #if WINDOWS_WPF // ShowGridLinesで表示する際に利用するペンの定義 private static readonly Pen _guidePen1 = new Pen(Brushes.Yellow, 1); private static readonly Pen _guidePen2 = new Pen(Brushes.Blue, 1) { DashStyle = new DashStyle(new double[] { 4, 4 }, 0) }; protected override void OnRender(DrawingContext dc) { base.OnRender(dc); // ShowGridLinesが有効な場合、各種エレメントを描画する前に、ガイド用のグリッドを描画する。 if (this.ShowGridLines) { var gridNum = this.MaxDivision; var unit = this.ActualWidth / gridNum; for (var i = 0; i <= gridNum; i++) { var x = (int)(unit * i); dc.DrawLine(_guidePen1, new Point(x, 0), new Point(x, this.ActualHeight)); dc.DrawLine(_guidePen2, new Point(x, 0), new Point(x, this.ActualHeight)); } } } #endif } } ================================================ FILE: GridExtra.Uwp/GridExtra.Uwp.csproj ================================================  Debug AnyCPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0} Library Properties SourceChord.GridExtra GridExtra.Uwp ja-JP UAP 10.0.14393.0 10.0.10586.0 14 512 {A5A43C5B-DE2A-4C0C-9213-0A381AF9435A};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} AnyCPU true full false ..\Build\Uwp\Debug\ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP prompt 4 AnyCPU none true ..\Build\Uwp\Release\ TRACE;NETFX_CORE;WINDOWS_UWP prompt 4 x86 true bin\x86\Debug\ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP ;2008 full x86 false prompt x86 bin\x86\Release\ TRACE;NETFX_CORE;WINDOWS_UWP true ;2008 pdbonly x86 false prompt ARM true bin\ARM\Debug\ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP ;2008 full ARM false prompt ARM bin\ARM\Release\ TRACE;NETFX_CORE;WINDOWS_UWP true ;2008 pdbonly ARM false prompt x64 true bin\x64\Debug\ DEBUG;TRACE;NETFX_CORE;WINDOWS_UWP ;2008 full x64 false prompt x64 bin\x64\Release\ TRACE;NETFX_CORE;WINDOWS_UWP true ;2008 pdbonly x64 false prompt 14.0 ================================================ FILE: GridExtra.Uwp/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. [assembly: AssemblyTitle("GridExtra.Uwp")] [assembly: AssemblyDescription("GridExtra is a custom panel library for WPF/UWP.")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("SourceChord")] [assembly: AssemblyProduct("GridExtra.Uwp")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // Version information for an assembly consists of the following four values: // // Major Version // Minor Version // Build Number // Revision // // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.4.0.0")] [assembly: AssemblyFileVersion("0.4.0.0")] [assembly: ComVisible(false)] ================================================ FILE: GridExtra.Uwp/Properties/GridExtra.Uwp.rd.xml ================================================ ================================================ FILE: GridExtra.Uwp/project.json ================================================ { "dependencies": { "Microsoft.NETCore.UniversalWindowsPlatform": "5.1.0" }, "frameworks": { "uap10.0": {} }, "runtimes": { "win10-arm": {}, "win10-arm-aot": {}, "win10-x86": {}, "win10-x86-aot": {}, "win10-x64": {}, "win10-x64-aot": {} } } ================================================ FILE: GridExtra.Wpf/BreakPointsTypeConverter.cs ================================================ using System; using System.Collections.Generic; using System.ComponentModel; using System.Globalization; using System.Linq; using System.Text; using System.Threading.Tasks; namespace SourceChord.GridExtra { public class BreakPointsTypeConverter : TypeConverter { public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) { //return base.CanConvertFrom(context, sourceType); return sourceType == typeof(string); } public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) { var text = (string)value; var list = text.Split(',') .Select(o => o.Trim()) .Select(o => int.Parse(o)) .ToList(); if (list.Count() != 3) { throw new ArgumentException($"'{value}' Invalid value. BreakPoints must contains 3 items."); } return new BreakPoints() { XS_SM = list[0], SM_MD = list[1], MD_LG = list[2] }; } } } ================================================ FILE: GridExtra.Wpf/GridExtra.Wpf.csproj ================================================  Debug AnyCPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6} library Properties SourceChord.GridExtra GridExtra.Wpf v4.5 512 {60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC} 4 true full false ..\Build\Wpf\Debug\ TRACE;DEBUG;WINDOWS_WPF prompt 4 none true ..\Build\Wpf\Release\ TRACE;WINDOWS_WPF prompt 4 4.0 Code True True Resources.resx True Settings.settings True ResXFileCodeGenerator Resources.Designer.cs SettingsSingleFileGenerator Settings.Designer.cs ================================================ FILE: GridExtra.Wpf/Properties/AssemblyInfo.cs ================================================ using System.Reflection; using System.Resources; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Windows; // アセンブリに関する一般情報は以下の属性セットをとおして制御されます。 // アセンブリに関連付けられている情報を変更するには、 // これらの属性値を変更してください。 [assembly: AssemblyTitle("GridExtra.Wpf")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("SourceChord")] [assembly: AssemblyProduct("GridExtra.Wpf")] [assembly: AssemblyCopyright("Copyright © 2016")] [assembly: AssemblyTrademark("")] [assembly: AssemblyCulture("")] // ComVisible を false に設定すると、その型はこのアセンブリ内で COM コンポーネントから // 参照不可能になります。COM からこのアセンブリ内の型にアクセスする場合は、 // その型の ComVisible 属性を true に設定してください。 [assembly: ComVisible(false)] //ローカライズ可能なアプリケーションのビルドを開始するには、 //.csproj ファイルの CultureYouAreCodingWith を // 内部で設定します。たとえば、 //ソース ファイルで英語を使用している場合、 を en-US に設定します。次に、 //下の NeutralResourceLanguage 属性のコメントを解除します。下の行の "en-US" を //プロジェクト ファイルの UICulture 設定と一致するよう更新します。 //[assembly: NeutralResourcesLanguage("en-US", UltimateResourceFallbackLocation.Satellite)] [assembly:ThemeInfo( ResourceDictionaryLocation.None, //テーマ固有のリソース ディクショナリが置かれている場所 //(リソースがページ、 //またはアプリケーション リソース ディクショナリに見つからない場合に使用されます) ResourceDictionaryLocation.SourceAssembly //汎用リソース ディクショナリが置かれている場所 //(リソースがページ、 //アプリケーション、またはいずれのテーマ固有のリソース ディクショナリにも見つからない場合に使用されます) )] // アセンブリのバージョン情報は次の 4 つの値で構成されています: // // メジャー バージョン // マイナー バージョン // ビルド番号 // Revision // // すべての値を指定するか、下のように '*' を使ってビルドおよびリビジョン番号を // 既定値にすることができます: // [assembly: AssemblyVersion("1.0.*")] [assembly: AssemblyVersion("0.4.0.0")] [assembly: AssemblyFileVersion("0.4.0.0")] ================================================ FILE: GridExtra.Wpf/Properties/Resources.Designer.cs ================================================ //------------------------------------------------------------------------------ // // このコードはツールによって生成されました。 // ランタイム バージョン:4.0.30319.42000 // // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 // コードが再生成されるときに損失したりします。 // //------------------------------------------------------------------------------ namespace SourceChord.GridExtra.Properties { using System; /// /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 /// // このクラスは StronglyTypedResourceBuilder クラスが ResGen // または Visual Studio のようなツールを使用して自動生成されました。 // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] internal class Resources { private static global::System.Resources.ResourceManager resourceMan; private static global::System.Globalization.CultureInfo resourceCulture; [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] internal Resources() { } /// /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Resources.ResourceManager ResourceManager { get { if (object.ReferenceEquals(resourceMan, null)) { global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SourceChord.GridExtra.Properties.Resources", typeof(Resources).Assembly); resourceMan = temp; } return resourceMan; } } /// /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 /// [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] internal static global::System.Globalization.CultureInfo Culture { get { return resourceCulture; } set { resourceCulture = value; } } } } ================================================ FILE: GridExtra.Wpf/Properties/Resources.resx ================================================  text/microsoft-resx 2.0 System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 ================================================ FILE: GridExtra.Wpf/Properties/Settings.Designer.cs ================================================ //------------------------------------------------------------------------------ // // このコードはツールによって生成されました。 // ランタイム バージョン:4.0.30319.42000 // // このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 // コードが再生成されるときに損失したりします。 // //------------------------------------------------------------------------------ namespace SourceChord.GridExtra.Properties { [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "14.0.0.0")] internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); public static Settings Default { get { return defaultInstance; } } } } ================================================ FILE: GridExtra.Wpf/Properties/Settings.settings ================================================  ================================================ FILE: GridExtra.Wpf/WrapPanelEx.cs ================================================ using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; namespace SourceChord.GridExtra { public static class WrapPanelEx { public static Size GetOriginalSize(DependencyObject obj) { return (Size)obj.GetValue(OriginalSizeProperty); } private static void SetOriginalSize(DependencyObject obj, Size value) { obj.SetValue(OriginalSizeProperty, value); } // Using a DependencyProperty as the backing store for OriginalSize. This enables animation, styling, binding, etc... public static readonly DependencyProperty OriginalSizeProperty = DependencyProperty.RegisterAttached("OriginalSize", typeof(Size), typeof(WrapPanelEx), new PropertyMetadata(Size.Empty)); public static bool GetAdaptiveLayout(DependencyObject obj) { return (bool)obj.GetValue(AdaptiveLayoutProperty); } public static void SetAdaptiveLayout(DependencyObject obj, bool value) { obj.SetValue(AdaptiveLayoutProperty, value); } // Using a DependencyProperty as the backing store for AdaptiveLayout. This enables animation, styling, binding, etc... public static readonly DependencyProperty AdaptiveLayoutProperty = DependencyProperty.RegisterAttached("AdaptiveLayout", typeof(bool), typeof(WrapPanelEx), new PropertyMetadata(false, OnAdaptiveLayoutChanged)); private static void OnAdaptiveLayoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var panel = d as WrapPanel; var isEnabled = (bool)e.NewValue; if (panel == null) { return; } if (isEnabled) { SetOriginalSize(panel, new Size(panel.ItemWidth, panel.ItemHeight)); var layoutUpdateCallback = CreateLayoutUpdateHandler(panel); panel.LayoutUpdated += layoutUpdateCallback; SetLayoutUpdatedCallback(panel, layoutUpdateCallback); } else { var originalSize = GetOriginalSize(panel); panel.ItemWidth = originalSize.Width; panel.ItemHeight = originalSize.Height; panel.ClearValue(OriginalSizeProperty); // イベントの解除 var callback = GetLayoutUpdatedCallback(panel); panel.LayoutUpdated -= callback; } } private static EventHandler CreateLayoutUpdateHandler(WrapPanel panel) { var layoutUpdateCallback = new EventHandler((sender, args) => { if (panel == null) return; var orientaion = panel.Orientation; var originalSize = GetOriginalSize(panel); if (orientaion == Orientation.Horizontal) { if (double.IsNaN(originalSize.Width)) return; var count = Math.Floor(panel.ActualWidth / originalSize.Width); var size = panel.ActualWidth / count; panel.ItemWidth = size; } else { if (double.IsNaN(originalSize.Width)) return; var count = Math.Floor(panel.ActualHeight / originalSize.Height); var size = panel.ActualHeight / count; panel.ItemHeight = size; } }); return layoutUpdateCallback; } public static EventHandler GetLayoutUpdatedCallback(DependencyObject obj) { return (EventHandler)obj.GetValue(LayoutUpdatedCallbackProperty); } private static void SetLayoutUpdatedCallback(DependencyObject obj, EventHandler value) { obj.SetValue(LayoutUpdatedCallbackProperty, value); } // Using a DependencyProperty as the backing store for LayoutUpdatedCallback. This enables animation, styling, binding, etc... public static readonly DependencyProperty LayoutUpdatedCallbackProperty = DependencyProperty.RegisterAttached("LayoutUpdatedCallback", typeof(EventHandler), typeof(WrapPanelEx), new PropertyMetadata(null)); } } ================================================ FILE: GridExtra.sln ================================================  Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 14 VisualStudioVersion = 14.0.25420.1 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridExtra.Wpf", "GridExtra.Wpf\GridExtra.Wpf.csproj", "{631C583B-5E88-4ABD-9926-C18E4ADDF6C6}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GridExtra.Uwp", "GridExtra.Uwp\GridExtra.Uwp.csproj", "{FE7A5887-17BC-48E9-B601-815A2FDBF2A0}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "GridExtra.Shared", "GridExtra.Shared\GridExtra.Shared.shproj", "{4914D867-F667-4151-A039-3FDE665F3106}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Sample", "Sample", "{611249A1-CDE6-4AAD-B532-73007C552C77}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicSample.Wpf", "Sample\BasicSample.Wpf\BasicSample.Wpf.csproj", "{E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BasicSample.Uwp", "Sample\BasicSample.Uwp\BasicSample.Uwp.csproj", "{416D9AA6-F3E7-4338-B9A3-E060060DAF0C}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Nuget", "Nuget", "{E1C85495-293B-4198-845C-6D7068A1961E}" ProjectSection(SolutionItems) = preProject Nuget\GridExtra.nuspec = Nuget\GridExtra.nuspec Nuget\pack.bat = Nuget\pack.bat EndProjectSection EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution GridExtra.Shared\GridExtra.Shared.projitems*{4914d867-f667-4151-a039-3fde665f3106}*SharedItemsImports = 13 GridExtra.Shared\GridExtra.Shared.projitems*{631c583b-5e88-4abd-9926-c18e4addf6c6}*SharedItemsImports = 4 GridExtra.Shared\GridExtra.Shared.projitems*{fe7a5887-17bc-48e9-b601-815a2fdbf2a0}*SharedItemsImports = 4 EndGlobalSection GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Debug|ARM = Debug|ARM Debug|x64 = Debug|x64 Debug|x86 = Debug|x86 Release|Any CPU = Release|Any CPU Release|ARM = Release|ARM Release|x64 = Release|x64 Release|x86 = Release|x86 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|Any CPU.Build.0 = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|ARM.ActiveCfg = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|ARM.Build.0 = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|x64.ActiveCfg = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|x64.Build.0 = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|x86.ActiveCfg = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Debug|x86.Build.0 = Debug|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|Any CPU.ActiveCfg = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|Any CPU.Build.0 = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|ARM.ActiveCfg = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|ARM.Build.0 = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|x64.ActiveCfg = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|x64.Build.0 = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|x86.ActiveCfg = Release|Any CPU {631C583B-5E88-4ABD-9926-C18E4ADDF6C6}.Release|x86.Build.0 = Release|Any CPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|Any CPU.Build.0 = Debug|Any CPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|ARM.ActiveCfg = Debug|ARM {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|ARM.Build.0 = Debug|ARM {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|x64.ActiveCfg = Debug|x64 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|x64.Build.0 = Debug|x64 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|x86.ActiveCfg = Debug|x86 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Debug|x86.Build.0 = Debug|x86 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|Any CPU.ActiveCfg = Release|Any CPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|Any CPU.Build.0 = Release|Any CPU {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|ARM.ActiveCfg = Release|ARM {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|ARM.Build.0 = Release|ARM {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|x64.ActiveCfg = Release|x64 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|x64.Build.0 = Release|x64 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|x86.ActiveCfg = Release|x86 {FE7A5887-17BC-48E9-B601-815A2FDBF2A0}.Release|x86.Build.0 = Release|x86 {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|Any CPU.Build.0 = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|ARM.ActiveCfg = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|ARM.Build.0 = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|x64.ActiveCfg = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|x64.Build.0 = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|x86.ActiveCfg = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Debug|x86.Build.0 = Debug|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|Any CPU.ActiveCfg = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|Any CPU.Build.0 = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|ARM.ActiveCfg = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|ARM.Build.0 = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|x64.ActiveCfg = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|x64.Build.0 = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|x86.ActiveCfg = Release|Any CPU {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B}.Release|x86.Build.0 = Release|Any CPU {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|Any CPU.ActiveCfg = Debug|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|ARM.ActiveCfg = Debug|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|ARM.Build.0 = Debug|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|ARM.Deploy.0 = Debug|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x64.ActiveCfg = Debug|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x64.Build.0 = Debug|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x64.Deploy.0 = Debug|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x86.ActiveCfg = Debug|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x86.Build.0 = Debug|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Debug|x86.Deploy.0 = Debug|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|Any CPU.ActiveCfg = Release|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|ARM.ActiveCfg = Release|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|ARM.Build.0 = Release|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|ARM.Deploy.0 = Release|ARM {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x64.ActiveCfg = Release|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x64.Build.0 = Release|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x64.Deploy.0 = Release|x64 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x86.ActiveCfg = Release|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x86.Build.0 = Release|x86 {416D9AA6-F3E7-4338-B9A3-E060060DAF0C}.Release|x86.Deploy.0 = Release|x86 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection GlobalSection(NestedProjects) = preSolution {E180DF3E-1A9F-482E-A7E2-FD7FBB27514B} = {611249A1-CDE6-4AAD-B532-73007C552C77} {416D9AA6-F3E7-4338-B9A3-E060060DAF0C} = {611249A1-CDE6-4AAD-B532-73007C552C77} EndGlobalSection EndGlobal ================================================ FILE: LICENSE ================================================ MIT License Copyright (c) 2016 minami_SC Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: Nuget/GridExtra.nuspec ================================================  GridExtra 0.4.0 GridExtra SourceChord SourceChord https://github.com/sourcechord/GridExtra/blob/master/LICENSE https://github.com/sourcechord/GridExtra false GridExtra is a custom panel library for WPF/UWP. Copyright 2016 XAML WPF UWP Panel Library ================================================ FILE: Nuget/pack.bat ================================================ nuget pack GridExtra.nuspec pause ================================================ FILE: README.md ================================================ # GridExtra GridExtra is a custom panel library for WPF/UWP. * ResponsiveGrid * Custom Panel class that provides bootstrap like grid system. * Grid system * switch layout with window width. * XS(<768px), SM(<992px), MD(<1200px), LG(1200px<=) * 12 columns across the page.(customizable with MaxDivision property) * GridEx * Helper class that defines usefull attached properties for Grid panel. * WrapPanelEx * Helper class that provide adaptive layout for WrapPanel. ## install *Nuget Package* ``` Install-Package GridExtra ``` https://www.nuget.org/packages/GridExtra/ ### Preparation Add xmlns to xaml code. #### For WPF ```xml xmlns:ge="clr-namespace:SourceChord.GridExtra;assembly=GridExtra.Wpf" ``` #### For UWP ```xml xmlns:ge="using:SourceChord.GridExtra" ``` ## Usage ### ResponsiveGrid ResponsiveGrid provides the grid layout system that is similar to Bootstrap framework. ![demo](./docs/ResponsiveGrid/demo.gif) #### Example ```xml ``` *extra small device(~768px)* ![extra small device](./docs/ResponsiveGrid/capture1.png) *small device(~992px)* ![small device](./docs/ResponsiveGrid/capture2.png) #### Properties ##### Dependency Properties |Property Name|Type|Description| |-----|-----|-----| |MaxDivision|int|Gets or sets a value that determines grid divisions.| |BreakPoints|BreakPoints class|| |ShowGridLines|int|Gets or sets a value that indicates whether grid column's lines are visible within this ResponsiveGrid. | ##### Attached Properties |Property Name|Type|Description| |-----|-----|-----| |XS
SM
MD
LG
|int|Gets or sets a value that determines grid columns for XS(extra small), SM(small), MD(medium), LG(large) devices.| |XS_Offset
SM_Offset
MD_Offset
LG_Offset
|int|Gets or sets a value that determines grid columns offset for XS(extra small), SM(small), MD(medium), LG(large) devices.| |XS_Push
SM_Push
MD_Push
LG_Push
|int|Gets or sets a value that moves columns to right from the original position.| |XS_Pull
SM_Pull
MD_Pull
LG_Pull
|int|Gets or sets a value that moves columns to left from the original position.| ##### Compared to bootstrap |bootstrap|ResponsiveGrid| |-----|-----| |col-xs
col-sm
col-md
col-lg
|XS
SM
MD
LG
| |col-xs-offset
col-sm-offset
col-md-offset
col-lg-offset
|XS_Offset
SM_Offset
MD_Offset
LG_Offset
| |col-xs-push
col-sm-push
col-md-push
col-lg-push
|XS_Push
SM_Push
MD_Push
LG_Push
| |col-xs-pull
col-sm-pull
col-md-pull
col-lg-pull
|XS_Pull
SM_Pull
MD_Pull
LG_Pull
| |visibility-xs, visibility-sm,…
hidden-xs, hidden-sm,...|(T.B.D.)| #### attention ResponsiveGrid is not suitable for ItemsPanel, because it isn't implemented VirtualizingPanel class. If you use ResponsiveGrid in ListBox as ItemsPanel. Your ListBox become to not virtualize items of ListBox. ### GridEx GridEx is Helper class for defining Grid properties. ![demo](./docs/GridEx/demo.gif) #### Example1 (Row/Column Definition) ```xml