How to bind individual Border CornerRadius? - wpf

I made a round window with Border like this:
<Border CornerRadius="{Binding WindowCornerRadius}" Background="{StaticResource BackgroundDarkBrush}">
<Border.Effect>
<DropShadowEffect ShadowDepth="0" Opacity="0.2"></DropShadowEffect>
</Border.Effect>
</Border>
<Grid>
<Grid.RowDefinitions>
<!--Title Bar-->
<RowDefinition Height="{Binding TitleHeightGridLength}"></RowDefinition>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<!--Title Bar-->
<Border Background="{StaticResource TitleBrush}" CornerRadius="{Binding WindowCornerRadius,WindowCornerRadius,0,0}">
<Grid Grid.Column="0" Panel.ZIndex="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Button Style="{StaticResource SystemIconButton}" Command="{Binding MenuCommand}">
<Image Source="Images/Logo/Wink.png"></Image>
</Button>
</Grid>
</Border>
</Grid>
</Grid>
</Border>
As you see I changed Background of first GridRow and this prevents it to be round(To have corner radius) and I would like to correct it adding border to first GridRow But I failed. The code above gives me error in CornerRadius="{Binding WindowCornerRadius,WindowCornerRadius,0,0}" :
No constructor for type "Binding" has 4 arguments.
My question is am I doing it correct by adding another border? (If yes how can I Bind CornerRadius individually).

You cannot use a binding like this. A binding on CornerRadius will look for a Thickness-typed property from your DataContext, with the Path given inside the binding. The path is implicit in a binding, but you can set it explicitely : Property="{Binding Path=blabla}". More info here.
Does the CornerRadius dynamically change? Why?
Also have a look at this :
Binding only part of the margin property of WPF control

Related

Border Styling applied to all the child elements recursively

I am new to WPF and need your help in resolving my styling issue.
I have applied border styling to GRID as below
<Border CornerRadius="5" BorderBrush="Gainsboro" BorderThickness="1,1,0,0" Name="border1" Margin="90,54,20,50" >
<Border BorderBrush="Gray" CornerRadius="5" BorderThickness="0,0,1,1" >
<Border.Effect>
<DropShadowEffect BlurRadius="10" Direction="-50" ShadowDepth="7" />
</Border.Effect>
<Border.Child>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="356*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="446*" />
</Grid.ColumnDefinitions>
<TextBox Name="TB1" Style="{StaticResource CustomTextBoxStyle}" Grid.Column="1" Margin="46,79,400,277" Grid.Row="1" />
<ComboBox Height="24" Name="comboBox1" Width="110" Grid.Column="1" Margin="304,86,232,276" Grid.Row="1" />
</Grid>
</Border.Child>
</Border>
</Border>
Then I have placed text box and combo box in the grid with custom styling.
The problem is parent GRID's border style is applied to child TEXTBOX along with its own custom style properties.
Could you please help me out in this?
Thanks
Bharat
As per MSDN doucment -
When a BitmapEffect is applied to a layout container, such as
DockPanel or Canvas, the effect is applied to the visual tree of the
element or visual, including all of its child elements.
But, there is a workaround as described here and here to have another border with same position but without the effect, that would resolve the problem -
<Grid>
<Border Margin="10" BorderBrush="Red" BorderThickness="1">
<Border.Effect>
<DropShadowEffect Color="Gray"/>
</Border.Effect>
</Border>
<Border Margin="10">
<!-- controls -->
</Border>
</Grid>

TreeViewItem Tooltip Binding Not Working

I have a treeview. It's bound to an ObservableCollection called Nodes. The bound data on the tool tips is not showing:
<controls:TreeViewEx BorderThickness="0"
ItemsSource="{Binding Nodes}"
SelectedItemEx="{Binding SelectedTreeNode, Mode=TwoWay}">
<controls:TreeViewEx.ToolTip>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Grid.Row="0"
Grid.Column="0"
Source="/FMG.UI.WPF;component/Media/Images/job_128.png"
Height="16"
Width="16"/>
<TextBox Grid.Row="0"
Grid.Column="1"
Text="Job: "
FontWeight="Bold"/>
<TextBox Grid.Row="0"
Grid.Column="2"
Text="{Binding ToolTipHeader}"/>
<Border Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="3"
Height="2"
BorderBrush="Gray"/>
<TextBox Grid.Row="2"
Grid.Column="0"
Grid.ColumnSpan="3"
Text="{Binding ToolTipDetails}"/>
</Grid>
</controls:TreeViewEx.ToolTip>
</controls:TreeViewEx>
The tooltip pops up, but the ToolTipHeader and and ToolTipDetails are blank. The Output window says it can't find them on the view model. How do I make the binding look on the Node, not the view model?
You probably want to move the code; use the TreeView.ItemContainerStyle and add a Setter for the ToolTip, this will set a node-level tool-tip.
e.g.
<controls:TreeViewEx.ItemContainerStyle>
<Style TargetType="controls:TreeViewItemEx"> <!-- Guessing at item type name here -->
<Setter Property="Tooltip">
<Setter.Value>
<!-- Move your tooltip here -->
</Setter.Value>
</Setter>
</Style>
</controls:TreeViewEx.ItemContainerStyle>
Of course the DataContext for all the bindings in the tooltip will be the current item, if you want the context of the tree-view specify a RelativeSource that finds it (also prepend "DataContext" on the Path, otherwise you bind to properties directly on the tree-view).

How to organize elements inside a Button

i'm new to wpf .
i got a wpf button ,
in it i need to place 2 elements a textblock and a viewbox encapsulating a canvas
the problem is i can't seem to see the canvas at all , unless i give it static values for its size
<Button Margin="10,30,10,10" Padding="0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Me" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"></TextBlock>
<Viewbox Margin="0,0,0,5">
<Canvas Background="red" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Row="0" Grid.Column="1" >
<Ellipse HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Stroke="Black" StrokeThickness="4" ></Ellipse>
</Canvas>
</Viewbox>
</Grid>
</Button>
iv'e also attempted this using a stack panel with an horizontal orintation
in any case the canvas does not show
any thoughts of what i'm doing wrong ?
thanks.
Attached Grid properties only work when at the Grid-child-level, i.e. the properties set on the canvas do not take effect they should be set on the container, the ViewBox which is a direct child of the Grid.
Viewboxes only work if the content has a concrete size, you probably need neither the ViewBox nor the Canvas. If you want the Ellipse to be a circle set Stretch="Uniform"
The contents of Buttons do not stretch by default you should set HorizontalContentAligment and its vertical counterpart to Stretch.
e.g.
<Button Margin="10,30,10,10" Padding="0" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<TextBlock Text="Me" Grid.Row="0" Grid.Column="0" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"></TextBlock>
<Ellipse Stretch="Uniform" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Stroke="Black" StrokeThickness="4"></Ellipse>
</Grid>
</Button>

Drag N drop images in a viewbox

I have a usercontrol with 6 viewbox, each can have an image. I have not set the width or height of the usercontrol(not even the viewboxes). At first the viewboxes are empty.I can add the images dynamically.
<Grid x:Name="DashBoardGrid" DockPanel.Dock="Right">
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="200*"></RowDefinition>
<RowDefinition Height="10"></RowDefinition>
<RowDefinition Height="200*"></RowDefinition>
<RowDefinition Height="20"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"></ColumnDefinition>
<ColumnDefinition Width="200*"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="200*"></ColumnDefinition>
<ColumnDefinition Width="10"></ColumnDefinition>
<ColumnDefinition Width="200*"></ColumnDefinition>
<ColumnDefinition Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Border Grid.Row="1" Grid.Column="1">
<DockPanel x:Name="dockPanel1" Margin="10,30,10,10" >
<TextBlock x:Name="TitleTxtblk1" DockPanel.Dock="Top" FontSize="10pt" TextWrapping="Wrap">screen 1</TextBlock>
<Viewbox x:Name="Viewbox1" MouseDown="Viewbox_MouseDown" MouseEnter="ScaleUp" MouseLeave="ScaleDown"
PreviewMouseLeftButtonDown="DockPanel_PreviewMouseLeftButtonDown" PreviewMouseMove="dockPanel_MouseMove"
Drop="dockPanel_Drop" DragEnter="dockPanel_DragEnter" AllowDrop="True">
</Viewbox>
</DockPanel>
</Border>
<Border Grid.Row="1" Grid.Column="3" >
<DockPanel x:Name="dockPanel2" Margin="10,30,10,10" >
<TextBlock x:Name="TitleTxtblk2" DockPanel.Dock="Top" FontSize="10pt" TextWrapping="Wrap">screen 2</TextBlock>
<Viewbox x:Name="Viewbox2" MouseDown="Viewbox_MouseDown" MouseEnter="ScaleUp" MouseLeave="ScaleDown"
PreviewMouseLeftButtonDown="DockPanel_PreviewMouseLeftButtonDown" PreviewMouseMove="dockPanel_MouseMove"
Drop="dockPanel_Drop" DragEnter="dockPanel_DragEnter" AllowDrop="True">
</Viewbox>
</DockPanel>
</Border>
I want to drag and drop the images from one viewbox to any other empty viewbox. But when the viewbox is empty, it is not visible at all. because it does not have a height or width. So i am not able to drop the image on it.
So what will i have to to such that when any one view box has an image all the view box have the same height and width? any other solution is welcome.
You could handle the drag/drop events in a parent control like the Border. And then you probably need a reference to your viewbox in your drag/drop methode. Try this:
<Border Tag="{Binding ElementName=Viewbox2,Path=.} … >
and in your drag/drop methode
ViewBox v = (sender as Border).Tag as ViewBox;

How do you override the opacity of a parent control in WPF?

When you set the opacity on a Grid in WPF, all the child elements appear to inherit its Opacity. How can you have a child element not inherit the parent's opacity?
For example, the following parent grid has one child grid in the middle with a background set to red, but the background appears pinkish because of the parent's opacity. I'd like the child grid to have a solid color, non-transparent background:
<Grid x:Name="LayoutRoot">
<Grid Background="Black" Opacity="0.5">
<Grid.RowDefinitions>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
</Grid.ColumnDefinitions>
<-- how do you make this child grid's background solid red
and not inherit the Opacity/Transparency of the parent grid? -->
<Grid Grid.Column="1" Grid.Row="1" Background="Red"/>
</Grid>
</Grid>
I was able to achieve something like this in pure xaml using a Brush to paint the main grids background.
This way only parent grid will have its opacity set and its child elements won't inherit it.
<Grid x:Name="LayoutRoot">
<Grid>
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.5"/>
</Grid.Background>
<Grid.RowDefinitions>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Grid.Row="1" Background="Red" />
</Grid>
</Grid>
You can just overlay two grids inside your layout grid. The first would be defined as your grid, minus your red innermost grid. The second would be defined with the same columns and rows, with a transparent background. The only child of this grid would be your innermost grid.
<Grid x:Name="LayoutRootNew"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Grid Background="Black" Opacity="0.5">
<Grid.RowDefinitions>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Grid.Row="0">
Here is some content in a somewhat transparent cell
</TextBlock>
</Grid> <!-- End of First Grid -->
<!-- Second grid -->
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
<RowDefinition Height="0.333*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
<ColumnDefinition Width="0.333*"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" Grid.Row="1" Background="Red">
<TextBlock Foreground="White" Text="Here Is Your Red Child" />
</Grid> <!-- Inner Child Grid -->
</Grid> <!-- End of Second Grid -->
</Grid> <!-- Layout Grid -->
If you want all the children of the parent container to set their own opacity regardless of the parents you can just set the alpha channel of the parent panel's background (instead of setting opacity) to get a slightly transparent background without impacting the child elements. Something like this, where the 0C in the background is the Alpha channel (the AA in AARRGGBB):
<Grid Grid.Column="0"
Grid.Row="1"
Background="Red"
Opacity="1" />
<Grid Grid.Column="1"
Grid.Row="1"
Background="Green" />
<Grid Grid.Column="2"
Grid.Row="1"
Background="Blue" />
However, if you want all the children except one to adhere to the parent's opacity that is a little more complicated. You might be able to do that with a ControlTemplate and some clever tricks with the Alpha channels or an opacity mask. If not you could build some sort of custom control that gave you the behavior you wanted. I would have to think about it for a bit to see what might be the best solution for that type of scenario.

Resources