Canvas Background color not showing - wpf

I created a UserControl to display a popup using a TextBlock within a Canvas. Everything seems to be working OK, except for the background color of the canvas. It is being rendered as transparent no matter what I try. I also tried adding a Rectangle and filling it but that isn't working either. Here's the code:
<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:Custom="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
xmlns:System="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
x:Class="PopupText.CanvasPopup"
d:DesignWidth="456"
d:DesignHeight="129">
<StackPanel x:Name="LayoutRoot"
Orientation="Horizontal">
<!--This button toggles the visibility of the popup-->
<Button x:Name="ActivateButton"
HorizontalAlignment="Left"
VerticalAlignment="Top"
BorderThickness="0"
Click="OnActivateButtonClicked">
<Image Source="/pushpin.png"
Width="36"
Height="36"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Stretch="Fill"
Margin="0" />
</Button>
<Canvas x:Name="PopupContainer"
HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="{Binding Width, ElementName=PopupText}"
Height="{Binding Height, ElementName=PopupText}"
Visibility="Collapsed">
<Canvas.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Color="#7FA79797"
Offset="1" />
</LinearGradientBrush>
</Canvas.Background>
<Rectangle Canvas.Left="0"
Canvas.Top="0"
RadiusX="20"
RadiusY="20"
Width="{Binding Width, ElementName=PopupText}"
Height="{Binding Height, ElementName=PopupText}">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Color="#7F67749D"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Fill>
<Rectangle.Stroke>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="Black"
Offset="0" />
<GradientStop Color="#7FC89B9B"
Offset="1" />
</LinearGradientBrush>
</Rectangle.Stroke>
</Rectangle>
<TextBlock x:Name="PopupText"
Text="A really long line of text that will either overflow or wrap"
TextWrapping="Wrap"
Width="350"
Canvas.Left="0"
Canvas.Top="0" />
</Canvas>
</StackPanel>
</UserControl>
Thanks for your help!

It looks like you want to bind the size of the Canvas to the actual size of the TextBlock not the values specified at design-time.
In that case, use a binding like this:
Width="{Binding ActualWidth, ElementName=PopupText}"
Height="{Binding ActualHeight, ElementName=PopupText}">

Your gradients appear to work if you set height manually. It would appear your height element binding isn't working as you expect it too.
I tested your Canvas in isolation with height 300, Rectangle height 200 and it didn't make much difference aesthetically what the height of the textblock was. Both the gradients worked fine, for the canvas and the rectangle.

You are binding the height property of the canvas and the rectangle to that of the textblock, but the textblock has an "auto" height property. XAML can't assign a height value to those elements for that reason. Try setting the height of the textblock manually rather than automatically. This will affect the other two elements right away.
P.S. If you remove Width="350" from the textblock, then the canvas and the rectangle will have 0 height and width on the stack panel. You need to set the height and width properties of the textblock manually since the other two elements depend on it.

Related

VB.net WPF textblock

can you please help me.
Im new in WPF and trying absolutely simple code. Have form with open save dialog. Path to a file im fill to a textblock and this string i need use in other module.
Without WPF i know how i can use it
frm_main.txt_path.text
But i cannot find this in WPF. This is my form. And i need use txt_path textblock
<Window x:Class="MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SCM_TO_BIESSE"
mc:Ignorable="d"
Title="Conversion SCM XXL code to Biesse XNC" Height="413.059" Width="647.202">
<Grid x:Name="frm_main" Margin="1,1,1,1.2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0*"/>
<ColumnDefinition Width="194*"/>
<ColumnDefinition Width="445*"/>
</Grid.ColumnDefinitions>
<Grid.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="#FF4396E4" Offset="1"/>
</LinearGradientBrush>
</Grid.Background>
<TextBlock x:Name="txt_path" HorizontalAlignment="Left" Margin="68,196,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Height="48" Width="285" Grid.ColumnSpan="3" Foreground="#FF6B5050">
<TextBlock.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF897F7F" Offset="0"/>
<GradientStop Color="#FFFAFAFA" Offset="1"/>
</LinearGradientBrush>
</TextBlock.Background>
</TextBlock>
<Button x:Name="btn_open" Content="Select file for conversion" HorizontalAlignment="Left" Margin="211.4,196,0,0" VerticalAlignment="Top" Width="160" Height="48" Grid.Column="2" RenderTransformOrigin="0.377,-0.663"/>
<Image Grid.Column="1" Margin="1,1,317.4,295" Source="new.jpg" Stretch="Fill" Grid.ColumnSpan="2"/>
<Button x:Name="btn_open_Copy" Content="Start Conversion" HorizontalAlignment="Left" Margin="65.4,304,0,29" Width="160" Grid.Column="2" RenderTransformOrigin="0.377,-0.663"/>
</Grid>
</Window>
Thanks very much for a help .
Marek
WPF is predicated (based, built) on binding to achieve a separation of concerns. You can do things the same way as WinForms but it isn't advised.
First (as mentioned in a comment) you need to use a TextBox, not a TextBlock. You haven't bound your TextBox to an underlying property (note that I've simplified this):
<TextBox x:Name="txt_path"
Text="{Binding YourTextProperty}"
Height="48" Width="285"
>
</TextBox>
</Grid>
You then have a public get/set string property called YourTextProperty on your viewmodel - then anything populated in to that TextBox will get automatically propagated to the underlying property (and vice versa - if you've correctly implemented INPC then any value populated into the property will get reflected in the textbox).

WPF OpacityMask moves with negative Margin of child element

When I place an element with a negative Margin into a ie. Border with an OpacityMask, the mask is moved as well.
Does anyone know if there is a way to apply an opacity mask to the viewport of the Border control regardless of any margins?
What I am trying to achieve is have only the center line of text of the Border's content should be fully visible. I move the Text (in my case an ItemsSource, actually) by setting the Margin of that element within the border to a negative value. This creates a cool effect that the other lines also loose in opacity and therefore the center line is plainly visible as being the current line. Unfortunately WPF also moves my Mask so as I move the content the fully visible line also moves upward within the Border control.
<Popup x:Name="PART_Popup"
VerticalOffset="{TemplateBinding TumblerVOffset}" IsOpen="{TemplateBinding IsTumblerVisible}"
PlacementTarget="{Binding RelativeSource={RelativeSource AncestorType={x:Type controls:TouchEditBox}}}"
MinWidth="{TemplateBinding TumblerWidth}" AllowsTransparency="True"
Height="{TemplateBinding TumblerHeight}" Placement="Relative">
<Border Background="{StaticResource TumblerBackground}" BorderBrush="White" BorderThickness="1">
<Border.OpacityMask>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Transparent" Offset="0.0" />
<GradientStop Color="Black" Offset="0.4" />
<GradientStop Color="Black" Offset="0.6" />
<GradientStop Color="Transparent" Offset="1.0" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.OpacityMask>
<ItemsControl ItemsSource="{Binding TumblerHandler.Tumblers, RelativeSource={RelativeSource TemplatedParent}}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
</ItemsControl>
</Border>
</Popup>
I found a solution - set ClipToBounds="True" on the Container which holds the elements who's Margin is negative (in my case the ItemsControl).

Drop event not firing for stackpanel in wpf

I have a grid, which contains a Canvas and StackPanel on same level. I mean the StackPanel placed on the top of the canvas. The canvas contains multiple elements which should be dragable. And I have to handle the Drop event of the StackPanel. The drop event not working if the stackpanel does not contain any child elements, even if I set the height for stackpanel. If I set the Background property for StackPanel it will work, but in this case the mousemove events of canvas child elements(below stackpanel) not working.
Here is the XAML
<Grid>
<jas:DragCanvas
x:Name="dragCanvas"
Grid.Row="1"
AllowDragging="{Binding ElementName=btnAllowDragging, Path=IsChecked}"
AllowDragOutOfView="{Binding ElementName=btnAllowDragOutOfView, Path=IsChecked}"
>
<Ellipse
Canvas.Left="100" Canvas.Bottom="100"
Width="65" Height="70">
<Ellipse.Fill>
<LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="LightGray" Offset="0" />
<GradientStop Color="Black" Offset="0.75" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Ellipse.Fill>
</Ellipse>
</jas:DragCanvas>
<DockPanel LastChildFill="False">
<Border DockPanel.Dock="Left" BorderBrush="Black" BorderThickness="2">
<StackPanel x:Name="stackPanel" Drop="StackPanel_Drop" AllowDrop="True">
<Border Height="100" Width="100" Background="Red"></Border>
</StackPanel>
</Border>
</DockPanel>
</Grid>

Keeping WPF grids from getting out of parent bounds

In my UI, I have a big grid with two columns and one row. in the right column, I have a grid with three rows where in the top row I have a user control, and in the two bottom rows I have two Expander objects, each containing an ItemsControl with a list that gets populated in runtime. Sometimes, that list gets really long and "spills" from the screen towards the bottom.
What I want to do is to allow the user to see both expanders, be able to expand or collapse them while keeping them both in sight. I tried wrapping them in WrapPanels or StackPanel but to no avail.
Here's some code to help explain my problem:
<Grid Grid.Row="1" x:Name="grid1">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Expander Grid.Row="0" Header="Expander 1" x:Name="expander1" FontSize="14" IsExpanded="True">
<Expander.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC4C4C4" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Expander.Background>
<ContentPresenter Content="{Binding ViewModel.OpenAlerts, ElementName=m_viewControl}" ClipToBounds="True"/>
</Expander>
<Expander Grid.Row="1" x:Name="expander2" Header="Expander 2" FontSize="14" IsExpanded="True">
<Expander.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC4C4C4" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Expander.Background>
<ContentPresenter Content="{Binding ViewModel.ClosedAlerts, ElementName=m_viewControl}" ClipToBounds="True"/>
</Expander>
</Grid>
Any assistance or tips will be highly appreciated!
Thanks,
John.
It's really not clear what kind of UI elements you have in the Expanders, but a ListBox for example works just fine, it will show scrollbars when the number of items is larger that the allocated space in the Grid row.
But you can also wrap you list of items in a StackPanel inside a ScrollViewer, which also works fine:
<Expander Grid.Row="0" Header="Expander 1" x:Name="expander1" FontSize="14" IsExpanded="True">
<Expander.Background>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFC4C4C4" Offset="0" />
<GradientStop Color="White" Offset="1" />
</LinearGradientBrush>
</Expander.Background>
<ScrollViewer>
<StackPanel>
<TextBlock>Test</TextBlock>
<TextBlock>Test</TextBlock>
<TextBlock>Test</TextBlock>
<!-- etc.. -->
<!-- etc.. -->
</StackPanel>
</ScrollViewer>
</Expander>
That should also work for you.

WPF store layout in resources

I have application where default Window's borders switched off
Window tag definition looks like this:
<Window x:Class="TEA.UI.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Title" WindowStyle="None" AllowsTransparency="True" Background="Transparent">
Inside Window tag, there is Grid panel, it contains several Rectangle shapes and few other grids.
It looks like this:
<Grid>
<!-- WINDOW BACKGROUND -->
<Rectangle Stroke="#FF214E80" RadiusX="3" RadiusY="3" ClipToBounds="True">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF193C6C" Offset="0"/>
<GradientStop Color="#FF2A65A4" Offset="1"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- // WINDOW BACKGROUND -->
<!-- HEADER HIGHLIGHT2 -->
<Rectangle HorizontalAlignment="Stretch" Margin="2,2,2,0" VerticalAlignment="Top" Height="62" RadiusX="2" RadiusY="2">
<Rectangle.Fill>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00193C6C" Offset="1"/>
<GradientStop Color="#4C96ABC3" Offset="0"/>
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<!-- // HEADER HIGHLIGHT2 -->
<Grid>
....
</Grid>
These rectangle shapes are used in other window dialogs as well.
My questions are:
How would it be possible to store these recatangles inside WPF resource dictionary?
How would I be able to reference them?
Actually the solution was quite simple
WPF UserControl did the trick for me
You can create a style in your resource dictionary for these items with setters for each property--one included below.
<Style TargetType="{x:Type Rectangle}" x:Key="WindowBackground">
<Setter Property="Stroke" Value="#FF214E80"/>
</Style>
Then in your window you can reference the style as such..
<Rectangle Style="{StaticResource WindowBackground}"/>

Resources