Drop event not firing for stackpanel in wpf - 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>

Related

xaml wpf - Gradient Brush resource doesn't work correctly

I'm already desperate to find the answer why this happens... here's my code:
ResourceDictionary
<Color x:Key="ControlStrokeColorDefault">#0F000000</Color>
<Color x:Key="ControlStrokeColorSecondary">#29000000</Color>
<LinearGradientBrush x:Key="ControlElevationBorderBrush" MappingMode="Absolute" StartPoint="0,0" EndPoint="0,3">
<LinearGradientBrush.RelativeTransform>
<ScaleTransform CenterY="0.5" ScaleY="-1" />
</LinearGradientBrush.RelativeTransform>
<LinearGradientBrush.GradientStops>
<GradientStop Offset="0.33" Color="{DynamicResource ControlStrokeColorSecondary}" />
<GradientStop Offset="1.0" Color="{DynamicResource ControlStrokeColorDefault}" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
Panel
<Grid Background="#29000000">
<WrapPanel Background="#F7F7F7" VerticalAlignment="Center" HorizontalAlignment="Center">
<Border Margin="20" Width="100" Height="60" BorderThickness="2" BorderBrush="{DynamicResource ControlElevationBorderBrush}">
<TextBlock>Ok</TextBlock>
</Border>
<Border Margin="20" Width="100" Height="100" BorderThickness="2" BorderBrush="{DynamicResource ControlElevationBorderBrush}">
<TextBlock>???</TextBlock>
</Border>
</WrapPanel>
</Grid>
As a Result, I get that the gradient is calculated only on the first element... is this a wpf bug or am I missing something?
this is because of ScaleY="-1" in ScaleTransform
Scale creates different sizes at different heights

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).

WPF binding issues with resource dictionaries

I have developed a custom data grid control. This control has two parts, one is the custom template used by the data grid itself and the other is my custom control which adds a title area to the data grid.
I have a class called CustomDataGrid, here is the XAML.
<UserControl x:Class="MDT_Designer.Presentation.ScreenControls.CustomDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
Name="CDataGrid" >
<UserControl.Resources>
<ResourceDictionary x:Key="Dictionary" Source="CustomizedControls.xaml"/>
</UserControl.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="{Binding ElementName=CDataGrid, Path=TitleAreaHeight}"/>
<RowDefinition Height="{Binding ElementName=CDataGrid, Path=GridAreaHeight}"/>
</Grid.RowDefinitions>
<Grid Name="TitleArea" DockPanel.Dock="Top" Background="{Binding ElementName=CDataGrid, Path=TitleBackColor}" >
<Viewbox HorizontalAlignment="{Binding ElementName=CDataGrid, Path=TitleAlignment}">
<TextBlock Name="TitleText" Text="{Binding ElementName=CDataGrid, Path=Title}" Margin="2,0,0,0" FontFamily="{Binding ElementName=CDataGrid, Path=TitleFontFamily}" Foreground="{Binding ElementName=CDataGrid, Path=TitleTextColor}"/>
</Viewbox>
</Grid>
<DataGrid Name="DataGridArea" Grid.Row="1" IsReadOnly="True" HorizontalGridLinesBrush="DarkGray" VerticalGridLinesBrush="DarkGray" VerticalScrollBarVisibility="Visible" Background="AliceBlue" >
</DataGrid>
</Grid>
</UserControl>
In my CustomDataGrid.xaml.cs file I have defined properties as such.
public static DependencyProperty TitleAlignmentProperty = DependencyProperty.Register("TitleAlignment", typeof(HorizontalAlignment), typeof(CustomDataGrid));
public HorizontalAlignment TitleAlignment
{
get { return (HorizontalAlignment)base.GetValue(TitleAlignmentProperty); }
set { base.SetValue(TitleAlignmentProperty, value); }
}
I am just showing one as a sample, and this works. I do wish that I could change the binding in the XAML to get rid of ElementName=CDataGrid, but any way I have as an alternative doesn't work.
Now to my problem. My custom template for the data grid control itself is stored in the dictionary CustomizedControls.xaml.
Here is one example of binding issues. I had to create this resource.
<LinearGradientBrush x:Key="HeaderBackgroundBrush" EndPoint="0.5,1" StartPoint="0.5,0" >
<GradientStop Color="{DynamicResource {x:Static SystemColors.ControlLightColorKey}}" Offset="0" />
<GradientStop Color="{DynamicResource {x:Static SystemColors.ControlDarkColorKey}}" Offset="1" />
</LinearGradientBrush>
Then I use it in Border definition for the column header.
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridColumnHeader}">
<Grid>
<Border x:Name="columnHeaderBorder" BorderThickness="1" Padding="3,0,3,0"
Background="{DynamicResource HeaderBackgroundBrush}">
<Border.BorderBrush>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="{DynamicResource BorderLightColor}" Offset="0" />
<GradientStop Color="{DynamicResource BorderDarkColor}" Offset="1" />
</LinearGradientBrush>
</Border.BorderBrush>
<ContentPresenter x:Name="columnHeaderPresenter" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}" Style="{DynamicResource HeaderContentStyle}" />
</Border>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Then to change it in my code behind I have to do this.
LinearGradientBrush headerBrush = (LinearGradientBrush)TryFindResource("HeaderBackgroundBrush");
headerBrush.GradientStops[0] = new GradientStop(brush.Color, 0.0);
I cannot change the brush itself, I can just change a property of the brush. I have tried every binding technique I can think of, but nothing seems to work when the style is in a dictionary.
What I would like to be able to do is somehow bind something like BorderLightColor, which is BorderBrush setting, so that in my code behind I can change it's value.
Any help would make my day, it would make my whole weekend in fact. Thanks.
Why cant you change the brush? You should be able to just assign the brush reference to the control. Does this not work? FindResource should search the Parent Element of the FrameworkElement you are calling it on and up the tree, the application resources, then Themes ending in System Resources. Forgive my VB...
Private Sub Button_Click(ByVal sender as Object, ByVal e as System.Windows.RoutedEventArgs)
Dim MyBrush2 as Brush = Me.FindResource("Brush2")
Me.MyRect.Background = MyBrush2
End Sub
And the window contents:
<Window.Resources>
<LinearGradientBrush x:Key="Brush1" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="Black" Offset="0"/>
<GradientStop Color="White" Offset="1"/>
</LinearGradientBrush>
<LinearGradientBrush x:Key="Brush2" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FF0800FF" Offset="0"/>
<GradientStop Color="Red" Offset="1"/>
</LinearGradientBrush>
</Window.Resources>
<Grid x:Name="LayoutRoot">
<Grid x:Name="MyRect" HorizontalAlignment="Left" Margin="63,66,0,174" Width="242" Background="{DynamicResource Brush1}" />
<Button Content="Button" HorizontalAlignment="Right" Height="60" Margin="0,117,95,0" VerticalAlignment="Top" Width="156" Click="Button_Click"/>
</Grid>

StackPanel with rounded and degraded background

Im trying to create a stackpanel with a rounded background, that also has a linearbrush from grey to trasparent
I used the ideas exposed here to prevent clipping
http://chriscavanagh.wordpress.com/2008/10/03/wpf-easy-rounded-corners-for-anything/
The problem now is that the text inside the stackpanel also has degradation and then turns invisible
any help?
Similar question
How do I create a WPF Rounded Corner container?
Code:
<Border Margin="235,78,0,0" VerticalAlignment="Top" HorizontalAlignment="Left"
BorderBrush="Red" BorderThickness="1" CornerRadius="8" >
<Grid>
<Border Name="mask" CornerRadius="7">
<Border.Background>
<LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
<GradientStop Color="Gray" Offset="0"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Border.Background>
</Border>
<StackPanel Orientation="Horizontal" >
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
<Image Height="16" Width="16" RenderOptions.BitmapScalingMode="NearestNeighbor" />
<TextBlock Foreground="Black" Margin="5,0,3,0" Text="00620"/>
<TextBlock Foreground="Black" Margin="5,0,3,0" Text="Error sincronización" />
</StackPanel>
</Grid>
</Border>
This is due to the OpacityMask, try to remove these lines from your XAML:
<StackPanel.OpacityMask>
<VisualBrush Visual="{Binding ElementName=mask}"/>
</StackPanel.OpacityMask>
And it should work

Canvas Background color not showing

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.

Resources