Created
October 16, 2018 16:18
-
-
Save ImaginaryDevelopment/0377960c53f679626167ad8f309fa7ed to your computer and use it in GitHub Desktop.
Demonstrate making a Wpf Frame control's Arrows enlarging
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.Windows; | |
using System.Windows.Controls; | |
void Main() | |
{ | |
var w = new Window(); | |
var grid = new Grid(); | |
// Func<FrameworkElement,UIElement> getTemplateChild = x => { | |
// var flags = BindingFlags.NonPublic | BindingFlags.Instance | |
// var tcm = x.GetType().GetMember("get_TemplateChild", flags)[0] as MethodInfo; | |
// var result = tcm.Invoke(x,null); | |
// return result as UIElement; | |
// }; | |
grid.RowDefinitions.Add(new RowDefinition(){MinHeight=80,Height=new GridLength(80)}); | |
grid.RowDefinitions.Add(new RowDefinition(){Height=new GridLength(200)}); | |
grid.RowDefinitions.Add(new RowDefinition(){Height=new GridLength(200)}); | |
grid.Children.Add(GenerateDemoFrame(1)); | |
var frame2 = GenerateDemoFrame(2); | |
grid.Children.Add(frame2); | |
w.Content = grid; | |
w.Dump(); | |
FixArrowSize(frame2); | |
} | |
static Frame GenerateDemoFrame(int gridRow) { | |
var f = new Frame(); | |
f.NavigationUIVisibility = System.Windows.Navigation.NavigationUIVisibility.Visible; | |
var page = new Page() { Content = new Button() { Content = $"Hello from row {gridRow + 1} (index {gridRow})"}}; | |
f.Navigate(page); | |
f.SetValue(Grid.RowProperty,gridRow); | |
return f; | |
} | |
static UIElement GetTemplateChild(FrameworkElement x) | |
{ | |
var flags = System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance; | |
var tcm = x.GetType().GetMember("get_TemplateChild", flags)[0] as System.Reflection.MethodInfo; | |
var result = tcm.Invoke(x, null); | |
return result as UIElement; | |
} | |
// Define other methods and classes here | |
static DockPanel GetDockPanel(FrameworkElement sender) | |
{ | |
var child = GetTemplateChild(sender); | |
// if the frame has been drawn/nav enabled, child will be a border first | |
if (child is Border b) | |
{ | |
child = b.Child; | |
} | |
var dp = child as DockPanel; | |
return dp; | |
} | |
static void FixArrowSize(Frame frame) | |
{ | |
var dp = GetDockPanel(frame); | |
if (dp is null) | |
return; | |
var grid = dp.Children.OfType<Grid>().FirstOrDefault(); | |
var path = grid.Children.OfType<System.Windows.Shapes.Path>().FirstOrDefault(); | |
// we did it, we're going to be called multiple times, but only need to do our job once | |
if (path == null) | |
return; | |
grid.Children.Remove(path); | |
var size = 40.0; | |
grid.Children.OfType<Control>().ToList().ForEach(c => | |
{ | |
c.MinHeight = size; | |
c.MinWidth = size; | |
if (c is Button b) | |
{ | |
var content = b.Content; | |
var child = GetTemplateChild(b) as Grid; | |
child.MinHeight = size; | |
child.MinWidth = size; | |
//} else if(c is Menu m) | |
//{ | |
// var content = GetTemplateChild(m) as FrameworkElement; | |
// content.MinHeight = size; | |
// content.MinWidth = size; | |
} | |
}); | |
var cd = grid.ColumnDefinitions; | |
cd[0].Width = new GridLength(size); | |
cd[1].Width = new GridLength(size); | |
// no row definitions | |
var rd = grid.RowDefinitions; | |
grid.MinHeight = size; | |
// see if you can see the current height/width of the column/rows and adjust the definitions, see if that changes the size | |
//frame | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
open | |
module Option = | |
let inline ofCast<'t> (x:obj) = | |
match x with | |
| :? 't as v -> Some v | |
| _ -> None | |
module Seq = | |
let inline ofType<'t> (items:_ seq) = | |
items |> Seq.choose(box >> Option.ofCast<'t>) | |
module WpfHelpers = | |
open System.Reflection | |
let getChildren (x:Panel) = | |
x.Children | |
let getChildrenOfType<'t> (x:Panel) : 't seq = | |
x | |
|> getChildren | |
|> Seq.cast<obj> | |
|> Seq.ofType<'t> | |
let getTemplateChild(x :FrameworkElement) = | |
let flags = BindingFlags.NonPublic ||| BindingFlags.Instance | |
let tcm = x.GetType().GetMember("get_TemplateChild", flags).[0] :?> MethodInfo | |
let result = tcm.Invoke(x,null) | |
result :?> UIElement | |
let getDockPanel (sender:FrameworkElement) = | |
// if the frame has been drawn/nav enabled, child will be a border first | |
let rec tryDP tryAgain (x:UIElement):DockPanel= | |
match x with | |
| :? Border as b -> | |
if tryAgain then | |
tryDP false b.Child | |
else | |
failwith "Border found inside border?" | |
| :? DockPanel as dp -> | |
dp | |
| null -> | |
invalidArg "sender" "No dockpanel, sender was null" | |
| x -> | |
x.Dump() | |
failwithf "that's no dockpanel, it's a %sstation!" <| x.GetType().Name | |
getTemplateChild sender | |
|> tryDP true | |
let fixArrowSize (frame:Frame) = | |
let adjustGridControl size (c:Control) = | |
c.MinHeight <- size | |
c.MinWidth <- size | |
c | |
|> Option.ofCast<Button> | |
|> Option.iter(fun b -> | |
let content = b.Content | |
let child = getTemplateChild b :?> Grid | |
child.MinHeight <- size | |
child.MinWidth <- size | |
) | |
match getDockPanel frame with | |
| null -> () | |
| dp -> | |
let grid = | |
dp | |
|> getChildrenOfType<Grid> | |
|> Seq.head | |
grid | |
|> getChildrenOfType<System.Windows.Shapes.Path> | |
|> Seq.tryHead | |
|> Option.iter (fun path -> | |
grid.Children.Remove path | |
let size = 40.0 | |
grid | |
|> getChildrenOfType<Control> | |
|> Seq.iter (adjustGridControl size) | |
) | |
() | |
let window = Window() | |
let generateDemoFrame gridRow = | |
let f = System.Windows.Controls.Frame() | |
f.NavigationUIVisibility <- System.Windows.Navigation.NavigationUIVisibility.Visible | |
let page = | |
Page(Content=Button(Content=sprintf "Hello from row %i (index %i)" gridRow (gridRow + 1))) | |
f.Navigate(page) |> ignore | |
f.SetValue(Grid.RowProperty,gridRow) | |
f | |
let frame2 = generateDemoFrame 2 | |
let grid = | |
let g = Grid() | |
g.RowDefinitions.Add(RowDefinition(MinHeight=80.,Height=GridLength 80.)) | |
g.RowDefinitions.Add(RowDefinition(Height=GridLength 200.)) | |
g.RowDefinitions.Add(RowDefinition(Height=GridLength 200.)) | |
generateDemoFrame 1 | |
|> g.Children.Add | |
|> ignore<int> | |
g.Children.Add frame2 |> ignore<int> | |
g | |
window.Content <- grid | |
window.Dump() | |
// change size after display | |
WpfHelpers.fixArrowSize frame2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
PresentationCore.dll | |
PresentationFramework.dll | |
System.Windows.Presentation.dll | |
WindowsBase.dll |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment