How do I restyle the XamNumericGrid up/down buttons? - wpf

In Infragistics NetAdvantage, how do I restyle the XamNumericEditor up/down buttons?
I looked in the DefaultStyles, and it's kind of tough to follow.
XamNumericEditor style is empty; it's simply an alias to XamMaskedEditor.
XamMaskedEditor, however, doesn't appear to have any up/down buttons defined in there. How does that work?
It'd be really great if I could find a solid not-overly-complex example.
Thanks to anyone who can help.

Here's the snippet from the DefaultStyle EditorsGeneric.xaml:
<Grid x:Name="PART_SpinButtons" DockPanel.Dock="Right" Visibility="{TemplateBinding SpinButtonVisibilityResolved}" Margin="0,1">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="1"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- AS 2/25/11 TFS67071 -->
<RepeatButton x:Name="spinUp" Style="{TemplateBinding SpinButtonStyle}" Focusable="false" ContentTemplate="{DynamicResource {x:Static igEditors:EditorsBrushKeys.IncreaseGlyphKey}}"/>
<RepeatButton x:Name="spinDown" Style="{TemplateBinding SpinButtonStyle}" Focusable="false" Grid.Row="2" ContentTemplate="{DynamicResource {x:Static igEditors:EditorsBrushKeys.DecreaseGlyphKey}}"/>
</Grid>
As you can see, you can set the SpinButtonStyle to change the look and feel of the spinButton in your application. If you want to change the content too (up/down arrows in the buttons), you can just override the EditorBrushKeys Resources.
Here's an example on how to change the style:
<Grid>
<Grid.Resources>
<!-- Change Content of the Repeat Buttons -->
<DataTemplate x:Key="{x:Static igEditors:EditorsBrushKeys.IncreaseGlyphKey}">
<Path
Width="7"
Height="4"
Data="M 0 4 L 8 4 L 4 0 Z"
Fill="{DynamicResource {x:Static igEditors:EditorsBrushKeys.DropdownBtnGlyphNormalForegroundFillKey}}"/>
</DataTemplate>
<DataTemplate x:Key="{x:Static igEditors:EditorsBrushKeys.DecreaseGlyphKey}">
<Path
Width="7"
Height="4"
Data="M 0 0 L 4 4 L 8 0 Z"
Fill="{DynamicResource {x:Static igEditors:EditorsBrushKeys.DropdownBtnGlyphNormalForegroundFillKey}}"/>
</DataTemplate>
<!-- Change properties on the button -->
<Style x:Key="mySpinButtonStyle" TargetType="{x:Type RepeatButton}">
<Setter Property="Background" Value="Green"/>
</Style>
</Grid.Resources>
<igEditors:XamNumericEditor SpinButtonDisplayMode="Always" x:Name="myEditor" Value="10" Width="120" Height="40" SpinButtonStyle="{StaticResource mySpinButtonStyle}"/>
</Grid>

Related

Can I make two containers (e.g. Grid and Canvas) take the same space to combine their abilities?

I have the following layout:
The Rectangles are placed using a Grid. On top of that, I want to add more "fluid" stuff, like Paths and lines that would be located dynamically.
For instance:
the lines between the Rectangles, are stretched from one Rectangle's mid-point to the mid-point of the one below it
The left-manually-drawn-ugly-red-"path" originate from the mid-point of the left-half of the top-Rectangle, and go to the mid-point of the left Rectange below it.
So the question is: the Rectangles match Grid behavior, other stuff, like the lines, match Canvas behavior. How do I use the advantages of both these containers? can I lay one over the other?
You don't need to mix and match your controls at all... you can chose either a Gird or a Canvas control to draw on using a Path element. Clearly, I don't want to do it all for you, so this is just a basic example of drawing in a Grid:
The end result:
The XAML:
<Grid Width="800">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="{x:Type Rectangle}">
<Setter Property="Stroke" Value="Black" />
<Setter Property="Fill" Value="White" />
<Setter Property="StrokeThickness" Value="1" />
<Setter Property="Width" Value="250" />
<Setter Property="Height" Value="100" />
<Setter Property="Rectangle.RadiusX" Value="20" />
<Setter Property="Rectangle.RadiusY" Value="20" />
</Style>
</Grid.Resources>
<Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="0" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
<Path Grid.Row="1" Grid.RowSpan="2" Grid.Column="1" Data="M0,0 0,100" Stroke="Black" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" />
<Rectangle Grid.Row="0" Grid.ColumnSpan="2" />
<Rectangle Grid.Row="1" Grid.Column="0" />
<Rectangle Grid.Row="1" Grid.Column="1" />
<Rectangle Grid.Row="2" Grid.Column="0" />
<Rectangle Grid.Row="2" Grid.Column="1" />
<Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 0 -100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,150,0" />
<Path Grid.Row="0" Grid.RowSpan="2" Grid.ColumnSpan="2" Data="M0,0 A 100,100 90 0 1 100,100" Stroke="Red" StrokeThickness="2" Fill="{x:Null}" Height="100" VerticalAlignment="Stretch" HorizontalAlignment="Center" Margin="0,0,-250,0" />
</Grid>
You can also find the syntax that you need to use in the Path.Data property in the Path Markup Syntax page on MSDN.
Yes you can lay the Canvas on top of a Grid, but you probably don't want to.
<Grid x:Name="container">
<!-- We use this to put the two items in the same location -->
<!-- i.e. Row="0" Column="0" is implicit for both the canvas and the grid below-->
<Grid x:Name="rectangleGrid"/>
<Canvas x:Name="shapeCanvas"/>
</Grid>
It really is that simple, but lets have a look at what we have now.
The shapeCanvas will be in front of the rectangleGrid (and if it isn't just tweak its ZIndex). If it has a non-transparent BackColor then you won't of course see the rectangleGrid, so you will need to sort that out.
If we want to line up the right hand red-line of yours we need to work out where to draw it from. Given that gridColumns don't expose sizes, then that's leftRectangle.ActualWidth + leftRectangle.Margin.Left + leftRectangle.Margin.Right + rightRectangle.Margin.Left + (rightRectangle.ActualWidth/2) and topRectangle.ActualHeight + topRectangle.Margin.Top + someConstantForHowTallThatSpacerRowIs + rightRectangle.Margin.Top + (rightRectangle.Height/2). Ouch
If we resize the container, then the rectangleGrid will also resize, but if you have used start-sizing for your columns then the rectangles all just resized. Now I have to go and recalculate all the sizes again.
So at this point, I'd start asking myself if I really wanted the rectangleGrid to handle the sizing or maybe I should just put everything into the Canvas.
You don't need to resize (although be careful because there are lots of high DPI screens out there now)
If you resize then the sizes are much simpler (e.g. if we assume that our margins are rectangles are 3/4 of the size and the margins 1/8 each side) so that redline top point now becomes shapeCanvas.Size *11/16 and (shapeCanvas.Height - someConstantForHowTallThatSpacerRowIs)/14

Adding line to a shape in XAML

I am modifying the button visual appearance in my XAML code with a hexagon. Now, I want to add 2 lines to the two outer edges of the hexagon like the image below:
https://skydrive.live.com/redir.aspx?cid=204df65b0e6e1655&resid=204DF65B0E6E1655!117&parid=204DF65B0E6E1655!107&authkey=!AEzKZRmwMNhBWxM
Can anyone tell how and where to add it ? My code is something like this
<Page.Resources>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Canvas>
<Polygon Canvas.Top="30" Points=
"430,0
400,32
-30,32
-60,0
-30,-32
400,-32"
Stroke="Brown" StrokeThickness="10"/>
<ContentPresenter Canvas.Left="80" Foreground="White" FontSize="40"></ContentPresenter>
</Canvas>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>
<Grid Background="Black">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button Grid.Row="1" Margin="40,-100 0,-50" HorizontalAlignment="Center">Hello World</Button>
</Grid>
I cant get the line to connect to those edges and spread all the way to the page end.
Any idea ?
Do you want this within your button style? I was able to achieve this through the XAML button control template code below.
I put separators in a grid and then put rectangles on top them to add stroke to the image.
I also added an upper margin of 2 onto the polygon to align with the rectangles.
<ControlTemplate TargetType="Button">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="500"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Rectangle Fill="White" Grid.Column="0"/>
<Rectangle Fill="White" Grid.Column="2"/>
<Separator Background="White" Grid.Column="0"/>
<Separator Background="White" Grid.Column="2"/>
<Canvas Grid.Column="1" Margin="64,2,0,0">
<Polygon Points=
"430,0
400,32
-30,32
-60,0
-30,-32
400,-32"
Stroke="Brown" StrokeThickness="10"/>
<ContentPresenter Canvas.Left="80" Foreground="White" FontSize="40"/>
</Canvas>
</Grid>
</ControlTemplate>

SL 4: Strange behavior with templated control

We have some xaml:
<Style TargetType="local:V_RelLine">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:V_RelLine">
<Grid x:Name="LayoutRoot">
<VisualStateManager.VisualStateGroups>
</VisualStateManager.VisualStateGroups>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Ellipse x:Name="startArrow" Height="20" Width="60" Fill="Green" Stroke="Blue" Visibility="Visible" />
<Path x:Name="LinePathPart" Visibility="Visible" Stroke="Red" StrokeDashArray="2 2" StrokeThickness="2"
>
<Path.Data>
<PathGeometry x:Name="LinePathGeometry" >
<PathFigure x:Name="linePathBezierFigure" >
<BezierSegment x:Name="linePathBezierSegment" />
</PathFigure>
</PathGeometry>
</Path.Data>
</Path>
<Ellipse x:Name="endArrow" Height="20" Width="20" Fill="Red" Stroke="Red" Visibility="Visible" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
And in the code behind:
LinePathBezierFigure.StartPoint = startPoint;
Canvas.SetLeft(startArrow, startPoint.X);
Canvas.SetTop(startArrow, startPoint.Y);
/* similar for endArrow */
At runtime, startArrow and endArrow end up at the same point (even though they were set to different locations), as though they ended up at 0,0.
In fact, a subsequent call to Canvas.GetLeft(startArrow) show that it is at 0,0.
What is going on? Why are different objects in the same template, assigned the same coordinates, ending up in different locations?
Thanks for any insight in to this....
Just a thought but Canvas.Left and Canvas.Top normally only work well when the elements are placed in a Canvas rather than a Grid like you are using currently.

How to disable drag thumb on a ScrollBar in WPF?

Two question:
How to disable drag thumb on a ScrollBar in WPF?
Is there a way to limit drag thumb position? like LargeChange or SmallChange?
Edit the template of the ScrollBar control and set the IsEnabled property of the Thumb to false
Not sure you can do that directly from code or XAML but you might add 2 new DP to a control which inherits the ScrollBar class and then change the template to have this new feature
Maybe it will be usefull for someone
If you wanna disable drag thumb there two way:
Rewrite controll for your scrollbar
In controll template do not rewrite thumb, just use rectangle or just leave it empty
Example:
<Style TargetType="{x:Type ScrollBar}">
<Setter Property="Background" Value="{StaticResource BackgroundColor}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ScrollBar}">
<Grid x:Name="Bg" SnapsToDevicePixels="true">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
<RowDefinition Height="0.00001*"/>
<RowDefinition MaxHeight="{DynamicResource {x:Static SystemParameters.VerticalScrollBarButtonHeightKey}}"/>
</Grid.RowDefinitions>
<Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Row="1" />
<RepeatButton Grid.Row="0" Command="ScrollBar.PageUpCommand" Style="{StaticResource ScrollBarButton}" Content="M 0 4 L 8 4 L 4 0 Z"/>
<Rectangle Grid.Row="1" VerticalAlignment="Top" x:Name="ThumbReplacer" Fill="{DynamicResource ScrollColor}"/>
<RepeatButton Grid.Row="2" Command="ScrollBar.PageDownCommand" Style="{StaticResource ScrollBarButton}" Content="M 0 0 L 4 4 L 8 0 Z"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

Style a border with a different brush color for each corner

I have created a static resource defining the border of a specific item in my xaml, but I can't find a good way to define a unique color for each side!
xaml:
<Border Style="{StaticResource SidePanelBorder}">
<!-- rest of the xaml -->
</Border>
StaticResource:
<Style x:Key="SidePanelBorder">
<Setter Property="Control.BorderBrush" Value="#FF363636" />
<Setter Property="Control.BorderThickness" Value="1" />
</Style>
But I want to define one color for each side of the border, and eventually also a different Border thickness.
Any good techniques out there doing this?
Seems very hacky, but you could define borders within borders, and make only 1 side have a thickness. For example
<Border BorderThickness="0,0,0,10" BorderBrush="Green">
<Border BorderThickness="0,0,10,0" BorderBrush="Blue">
<Grid>
<Button>Hello</Button>
</Grid>
</Border>
</Border>
would give a green border on the bottom and a blue border to the right. Isn't the prettiest piece of Xaml though.
Another solution using one Border and a VisualBrush, allowing setting the Border's CornerRadius and BorderThickness:
<Border BorderThickness="10" CornerRadius="10" HorizontalAlignment="Right" Height="150" VerticalAlignment="Bottom" Width="150" Margin="0,0,92.666,42.667">
<Border.BorderBrush>
<VisualBrush>
<VisualBrush.Visual>
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Path x:Name="ColoredBorderLeft" Data="M0,0 L0,0 1,0.5 L1,0.5 0,1" Fill="Blue" Stretch="Fill" Grid.RowSpan="2"/>
<Path x:Name="ColoredBorderRight" Data="M1,0 L1,0 0,0.5 L0,0.5 1,1" Fill="Red" Stretch="Fill" Grid.Column="1" Grid.RowSpan="2"/>
<Path x:Name="ColoredBorderTop" Data="M0,0 L0,0 0.5,1 L0.5,1 1,0" Fill="Green" Stretch="Fill" Grid.ColumnSpan="2"/>
<Path x:Name="ColoredBorderBottom" Data="M0,1 L0,1 0.5,0 L0.5,0 1,1" Fill="Yellow" Stretch="Fill" Grid.Row="1" Grid.ColumnSpan="2"/>
</Grid>
</VisualBrush.Visual>
</VisualBrush>
</Border.BorderBrush>
</Border>
The Grid is needed to prevent the tips of the triangle Paths to "push through" into the border.
The Path.Name's can be used for DataBinding or setting the color from code behind.
you can have a DockPanel and can put 4 Borders inside it, each docked to different side.
like:
<DockPanel LastChildFill="true">
<Border DockPanel.Dock="Left" Background="Red"/>
<Border DockPanel.Dock="Top" Background ="Blue"/>
<Border DockPanel.Dock="Right" Background ="Yellow"/>
<Border DockPanel.Dock="Bottom" Background ="Green"/>
<Grid>
...........your control here
</Grid>
</DockPanel>
If you use a Grid you can have Border's overlay on one another to achieve the same affect. Just set the border thickness of the border color you want to show and have the other border thickness be 0.
<UserControl.Resources>
<Style x:Key="GreenBorder" TargetType="Border">
<Setter Property="BorderBrush" Value="Green" />
<Setter Property="BorderThickness" Value="1,1,1,0" />
</Style>
<Style x:Key="RedBorder" TargetType="Border">
<Setter Property="BorderBrush" Value="Red" />
<Setter Property="BorderThickness" Value="0,0,0,1" />
</Style>
</UserControl.Resources>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0" Style="{StaticResource GreenBorder}">
<!-- Content goes here -->
</Border>
<Border Grid.Column="0" Grid.Row="0" Style="{StaticResource RedBorder}">
</Border>
</Grid>
This will give a Green border to the left, top and right borders, but a Red border to the bottom border of the Grid cell.
there's no easy way to do this without writing your own control or subclassing border

Resources