ContentPresenter loads resource only first occurence [WPF] - c#

I have WPF view, where I use buttons with style that I created by myself. In this style I use some icon from resources, that I pass by TemplateBinding.
Unfortunately I faced strange problem: the resource is shown only at first occurrence of button with this style. In next buttons I have empty box.
Style:
<Style x:Key="TransparentStyle" TargetType="{x:Type Button}">
<Setter Property="BorderBrush" Value="LightSlateGray"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Grid>
<Rectangle Width="13" Height="15" x:Name="IconBrush">
<Rectangle.Fill>
<SolidColorBrush Color="DarkGray"></SolidColorBrush>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<VisualBrush Stretch="Fill">
<VisualBrush.Visual>
<ContentPresenter Content="{TemplateBinding Button.Content}" />
</VisualBrush.Visual>
</VisualBrush>
</Rectangle.OpacityMask>
</Rectangle>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="IconBrush"
Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
To="Black" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard>
<Storyboard>
<ColorAnimation Duration="0:0:0.1" Storyboard.TargetName="IconBrush"
Storyboard.TargetProperty="Fill.(SolidColorBrush.Color)"
To="DarkGray" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Usege:
<WrapPanel Grid.Column="2" Margin="20 0">
<Button Height="35" Width="35" Margin="3 3" Content="{StaticResource trash}" Style ="{StaticResource TransparentStyle}"/>
<Button Height="35" Width="35" Margin="3 3" Content="{StaticResource trash}" Style ="{StaticResource TransparentStyle}" />
</WrapPanel>
What is interesting, when I use another resources, they work at their first occurrences. So if I use another_res instead of trash, it works at first time.
How do I fix it?
EDIT:
Next tests show, that when I use any resource in style and problem repeats:
<VisualBrush.Visual>
<ContentPresenter Content="{DynamicResource some_resource}" />
</VisualBrush.Visual>
EDIT2:
The resource is defined in external source:
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Resources/Icons.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
As canvas:
<Canvas x:Key="trash" Width="24" Height="24">
<Path Data="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" Fill="Black" />
</Canvas>

Don't define your Icons like(I hope this is your problem as this is what people usually do, and Image is a FrameworkElement):
<Image Source="Resources/SOF.gif" x:Key="trash"/>
Define them like:
<ImageBrush ImageSource="Resources/SOF.gif" x:Key="trash"/>
and use ImageBrush like(in your style):
<Rectangle Width="113" Height="95" x:Name="IconBrush" Fill="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=Content}"/>
your Icons will be repeated on buttons like below:
Update:
try it like:
<VisualBrush x:Key="trash" >
<VisualBrush.Visual>
<Canvas Width="24" Height="24" >
<Path Data="M19,4H15.5L14.5,3H9.5L8.5,4H5V6H19M6,19A2,2 0 0,0 8,21H16A2,2 0 0,0 18,19V7H6V19Z" Fill="Black" />
</Canvas>
</VisualBrush.Visual>
</VisualBrush>
OutPut:(make sure to use Rectangle fill correctly as I have mentioned above)

Related

Parameterized ResourceDictionary - is this possible?

I want to create a control that's composed of a number of circling Ellipse objects, like this (excerpt):
<Canvas Width="100" Height="100">
<Canvas Width="100" Height="100">
<Ellipse Canvas.Left="46"
Width="8"
Height="8"
Fill="White" />
<Canvas.RenderTransform>
<RotateTransform x:Name="r0" Angle="0" CenterX="50" CenterY="50" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="0:0:0"
Storyboard.TargetName="r0"
Storyboard.TargetProperty="Angle"
To="360"
Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
<Canvas Width="100" Height="100">
<Ellipse Canvas.Left="46"
Canvas.Top="10"
Width="8"
Height="8"
Fill="White" />
<Canvas.RenderTransform>
<RotateTransform x:Name="r1" Angle="0" CenterX="50" CenterY="50" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="0:0:0.05"
Storyboard.TargetName="r1"
Storyboard.TargetProperty="Angle"
To="360"
Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
<Canvas Width="100" Height="100">
<Ellipse Canvas.Left="46"
Canvas.Top="20"
Width="8"
Height="8"
Fill="White" />
<Canvas.RenderTransform>
<RotateTransform x:Name="r2" Angle="0" CenterX="50" CenterY="50" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="0:0:0.1"
Storyboard.TargetName="r2"
Storyboard.TargetProperty="Angle"
To="360"
Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
<!-- ... -->
</Canvas>
Please note: All of the inner Canvas/Ellipse elements differ by:
Ellipse.Canvas.Top
RotateTransform.Name
DoubleAnimation.BeginTime
Now, I want to save me a lot of writing by creating a resource composed of:
The inner Canvas
The Ellipse therein
The RotateTransform therein
The EventTrigger therein
The DoubleAnimation within the Eventtrigger
My final control would rather resemble something like this:
<Canvas Width="100" Height="100">
{StaticResource myElem InnerTop=0, BeginTime="0:0:0.0"}
{StaticResource myElem InnerTop=10, BeginTime="0:0:0.05"}
{StaticResource myElem InnerTop=20, BeginTime="0:0:0.1"}
</Canvas>
Is something like this possible by utilizing Resources only?
Or do I need to create a custom control, run by Code-Behind properties, to achieve this?
In the following I will describe two approaches to your issue using data templating or a UserControl.
Items Control and Data Templates
You can create a small utility type that exposes the properties that you want to customize.
public class CirclingEllipseProperties
{
public double Top { get; set; }
public TimeSpan BeginTime { get; set; }
}
Create a data template for the circling ellipse item that binds these properties.
<DataTemplate x:Key="CirclingEllipseTemplate" DataType="{x:Type local:CirclingEllipseProperties}">
<Canvas Width="100" Height="100">
<Ellipse Canvas.Left="46"
Canvas.Top="{Binding Top}"
Width="8"
Height="8"
Fill="White" />
<Canvas.RenderTransform>
<RotateTransform x:Name="r0" Angle="0" CenterX="50" CenterY="50" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="{Binding BeginTime}"
Storyboard.TargetName="r0"
Storyboard.TargetProperty="Angle"
To="360"
Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</DataTemplate>
Create an ItemsControl with a Canvas as ItemsPanel. Assign the data template as ItemTemplate and add an x:Array with CirclingEllipseProperties for each element as ItemsSource. You could even bind a collection of these elements from a view model or code-behind dynamically.
<ItemsControl Width="100"
Height="100"
ItemTemplate="{StaticResource CirclingEllipseTemplate}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemsSource>
<x:Array Type="{x:Type local:CirclingEllipseProperties}">
<local:CirclingEllipseProperties BeginTime="0:0:0" Top="0" />
<local:CirclingEllipseProperties BeginTime="0:0:0.05" Top="10" />
<local:CirclingEllipseProperties BeginTime="0:0:0.1" Top="20" />
</x:Array>
</ItemsControl.ItemsSource>
</ItemsControl>
Of course, you can also create a style for the ItemsControl, if you want to reuse it.
<Style x:Key="CirclingEllipseItemsControlStyle" TargetType="{x:Type ItemsControl}">
<Setter Property="Width" Value="100" />
<Setter Property="Height" Value="100" />
<Setter Property="ItemTemplate" Value="{StaticResource CirclingEllipseTemplate}" />
<Setter Property="ItemsPanel">
<Setter.Value>
<ItemsPanelTemplate>
<Canvas />
</ItemsPanelTemplate>
</Setter.Value>
</Setter>
</Style>
<ItemsControl Style="{StaticResource CirclingEllipseItemsControlStyle}">
<ItemsControl.ItemsSource>
<!-- ...items source as above. -->
</ItemsControl.ItemsSource>
</ItemsControl>
Create a User Control
Create a custom UserControl that exposes properties for Top and BeginTime.
<UserControl x:Class="YourApp.CirclingEllipseUserControl"
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:local="clr-namespace:YourApp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Width="100"
Height="100"
mc:Ignorable="d">
<Canvas>
<Ellipse Canvas.Left="46"
Canvas.Top="{Binding Top, RelativeSource={RelativeSource AncestorType={x:Type local:CirclingEllipseUserControl}}}"
Width="8"
Height="8"
Fill="White" />
<Canvas.RenderTransform>
<RotateTransform x:Name="r0" Angle="0" CenterX="50" CenterY="50" />
</Canvas.RenderTransform>
<Canvas.Triggers>
<EventTrigger RoutedEvent="Loaded">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation BeginTime="{Binding BeginTime, RelativeSource={RelativeSource AncestorType={x:Type local:CirclingEllipseUserControl}}}"
Storyboard.TargetName="r0"
Storyboard.TargetProperty="Angle"
To="360"
Duration="0:0:1.5" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Canvas.Triggers>
</Canvas>
</UserControl>
public partial class CirclingEllipseUserControl : UserControl
{
public static readonly DependencyProperty BeginTimeProperty = DependencyProperty.Register(
"BeginTime", typeof(TimeSpan), typeof(CirclingEllipseUserControl), new PropertyMetadata(TimeSpan.Zero));
public static readonly DependencyProperty TopProperty = DependencyProperty.Register(
"Top", typeof(double), typeof(CirclingEllipseUserControl), new PropertyMetadata(0.0));
public double Top
{
get => (double)GetValue(TopProperty);
set => SetValue(TopProperty, value);
}
public TimeSpan BeginTime
{
get => (TimeSpan)GetValue(BeginTimeProperty);
set => SetValue(BeginTimeProperty, value);
}
public CirclingEllipseUserControl()
{
InitializeComponent();
}
}
Add instances of the CirclingEllipseUserControl to your Canvas or create a DataTemplate for it like in the approach above to be able to dynamically bind items.
<Canvas Width="100" Height="100">
<local:CirclingEllipseUserControl BeginTime="0:0:0" Top="0" />
<local:CirclingEllipseUserControl BeginTime="0:0:0.05" Top="10" />
<local:CirclingEllipseUserControl BeginTime="0:0:0.1" Top="20" />
</Canvas>

Why won't my Template's TextBox bind

I am trying to do some binding. For the most part, my MVVM application is working fine but I now want to use a Template. In this case, I'm using XCeed chart which expose a SeriesTemplate.
My code is:
<UserControl
xmlns:xctk="http://schemas.xceed.com/wpf/xaml/toolkit"
x:Class="MyApp.AppUi.View.Graph.GraphView"
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"
xmlns:converter="clr-namespace:MyApp.AppUi.Converters"
>
<Grid>
<Grid.Resources>
<converter:MyIntConverter x:Key="MyIntConverter" />
<DataTemplate x:Key="MyLabelTemplate">
<TextBlock Text="{Binding Path=Text, Converter={StaticResource MyIntConverter}}" />
</DataTemplate>
<!--give it a name, Bind to above, choose property -->
<CollectionViewSource x:Key="GraphDataCollection" Source="{Binding GraphDataList}" />
<Style x:Key="TextBoxTextStyle" TargetType="TextBlock">
<Setter Property="HorizontalAlignment" Value="Center" />
<Setter Property="FontFamily" Value="Comic Sans MS"/>
<Setter Property="FontSize" Value="12"/>
<Style.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="19" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="FontSize" To="12" Duration="0:0:0.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Style.Triggers>
</Style>
<Style TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<ContentPresenter/>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="ContentTemplate">
<Setter.Value>
<DataTemplate>
<Grid Width="{Binding Path=ActualWidth, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"
Height="{Binding Path=ActualHeight, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}">
<Rectangle RadiusX="5" RadiusY="5" >
<Rectangle.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0.8" Duration="0:0:0.4"/>
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<EventTrigger.Actions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.4" />
</Storyboard>
</BeginStoryboard>
</EventTrigger.Actions>
</EventTrigger>
</Rectangle.Triggers>
<Rectangle.Fill>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<GradientStop Color="#FFffcf26" Offset="0.0" />
<GradientStop Color="#FFff7f04" Offset="1.0" />
</LinearGradientBrush>
</Rectangle.Fill>
</Rectangle>
<ContentPresenter VerticalAlignment="Center" Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"/>
</Grid>
</DataTemplate>
</Setter.Value>
</Setter>
</Style>
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding GraphData.ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>
</Grid.Resources>
<GroupBox Header="{Binding Title}">
<GroupBox.Background>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0" >
<GradientStop Offset="0" Color="#FF9d9d9d" />
<GradientStop Offset="1" Color="#FF666666" />
</LinearGradientBrush>
</GroupBox.Background>
<xctk:Chart Height="400" Width="400" ShowLegend="False">
<xctk:Chart.Areas>
<xctk:Area >
<xctk:Area.XAxis>
<xctk:Axis Title="Date"
GraduationMode="Manual"
LabelsType="DateTime"
ScaleMode="Automatic"
TitleMargin="10"
AxisLabelsLayout="ShowAll"
ShowArrow="False"
ShowAxis="True"
ShowGridLines="True"
ShowTicks="True"
ShowTickLabels="True"
ShowAxisLabel="True"
Reversed="False"
/>
</xctk:Area.XAxis>
<xctk:Area.YAxis>
<xctk:Axis Title="Google position"
ScaleMode="Manual"
TitleMargin="10"
AxisLabelsLayout="ShowAll"
ShowArrow="False"
ShowAxis="True"
ShowGridLines="True"
CustomRangeStart="1.00"
CustomRangeEnd="111.00"
ShowTicks="True"
ShowTickLabels="True"
ShowAxisLabel="True"
Reversed="False"
LabelTemplate="{StaticResource MyLabelTemplate}"
/>
</xctk:Area.YAxis>
<xctk:Area.Series>
<xctk:Series DataPointsSource="{Binding Source={StaticResource GraphDataCollection}}"
Template="{StaticResource SeriesTemplate}"
ShowPointsInLegend="true">
<xctk:Series.DataPointBindings>
<xctk:BindingInfo PropertyName="Y">
<xctk:BindingInfo.Binding>
<Binding Path="Position"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
<xctk:BindingInfo PropertyName="X">
<xctk:BindingInfo.Binding>
<Binding Path="Date"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
<xctk:BindingInfo PropertyName="Label">
<xctk:BindingInfo.Binding>
<Binding Path="ShortDate"/>
</xctk:BindingInfo.Binding>
</xctk:BindingInfo>
</xctk:Series.DataPointBindings>
</xctk:Series>
</xctk:Area.Series>
</xctk:Area>
</xctk:Chart.Areas>
</xctk:Chart>
</GroupBox>
</Grid>
and my ViewModel
public class GraphViewModel : BaseViewModel
{
public GraphViewModel(List<GraphData> data, string title )
{
this.GraphDataList = data;
this.Title = title;
}
public string Title { get; private set; }
public List<GraphData> GraphDataList { get; private set; }
}
And the DataContext is set in the Resource Dictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:graphView="clr-namespace:MyApp.AppUi.View.Graph"
xmlns:graphViewModel="clr-namespace:MyApp.AppUi.ViewModel.Graph"
xmlns:converter="clr-namespace:MyApp.AppUi.Converters"
>
<DataTemplate DataType="{x:Type graphViewModel:GraphViewModel}">
<graphView:GraphView />
</DataTemplate>
The chart displays as desired but, the SeriesTemplate does not bind. There is an error message in the ouput window, which I understand what the message is saying, but not how to fix it.
The error message is
System.Windows.Data Error: 40 : BindingExpression path error: 'ShortDate' property not found on 'object' ''ColumnPrimitiveInfo' (HashCode=39288004)'. BindingExpression:Path=ShortDate; DataItem='ColumnPrimitiveInfo' (HashCode=39288004); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
How do I get the binding to work for
<DataTemplate x:Key="SeriesTemplate">
<Button x:Name="Bar">
<StackPanel>
<TextBlock Text="{Binding GraphData.ShortDate}" Style="{StaticResource TextBoxTextStyle}" /> <!--THIS IS WHERE THE FAULT IS -->
</StackPanel>
</Button>
</DataTemplate>
XCeed have a working demo with source code, if you download the application, click on Charts -> Styling -> Column Series you can see that my code is very very similar. There's works, but mine does not and I can't see why. Please note, the graph itself displays, it's just the textbox is not showing. However, if I don't use binding, and just use Text="SomeWords" then it works fine
After a few hours of voodoo programming (where I just try different things at random) I found the solution.
<TextBlock Text="{Binding Path=Content.ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
I think this is because of (see the Button Setter in code of OP)
<ContentPresenter VerticalAlignment="Center" Content="{Binding Path=Content, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Button}}}"/>
Try this:
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding Path=ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>
From looking at the documentation hereon the XCeed documentation site it appears that you are adding an extra layer of indirection to the binding. Try binding directly to the GraphDataList
<xctk:Series DataPointsSource="{Binding Source={StaticResource GraphDataList}}"
Template="{StaticResource SeriesTemplate}"
ShowPointsInLegend="true">
and then in the series
<DataTemplate x:Key="SeriesTemplate">
<Button>
<StackPanel>
<TextBlock Text="{Binding Path=ShortDate}" Style="{StaticResource TextBoxTextStyle}" />
</StackPanel>
</Button>
</DataTemplate>

Change content of contentcontrol on mouse over (Freezable cannot be frozen)

I have a viewbox with a contentcontrol in it.
This contentcontrol refers to a canvas resource. Now on mouseover I want to change the content of the contentcontrol to another canvas resource.
code:
<StackPanel x:Name="ExtraActionsPanel" Background="{DynamicResource DarkGrey}" Grid.ColumnSpan="3" Height="38.5" VerticalAlignment="Bottom">
<Viewbox x:Name="ActionIconBox1" Width="50" >
<ContentControl Content="{DynamicResource action_message}"/>
</Viewbox>
</StackPanel>
My app.xaml where the resources are :
<Canvas x:Key="action_message" x:Shared="False" x:Name="action_message" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="38" Height="39.75" Canvas.Left="19" Canvas.Top="22" Stretch="Fill" Fill="{DynamicResource VeryLightBlue}" Data="F1 M 33,51L 36.4167,61.75L 24,51L 19,51L 19,22L 57,22L 57,51L 33,51 Z "/>
</Canvas>
<Canvas x:Key="action_message_focus" x:Shared="False" x:Name="action_message_focus" Width="76" Height="76" Clip="F1 M 0,0L 76,0L 76,76L 0,76L 0,0">
<Path Width="38" Height="39.75" Canvas.Left="19" Canvas.Top="22" Stretch="Fill" Fill="{DynamicResource Blue}" Data="F1 M 33,51L 36.4167,61.75L 24,51L 19,51L 19,22L 57,22L 57,51L 33,51 Z "/>
</Canvas>
I've tried to use a Storyboard and a trigger to change the content on mouse over but that gives me a exception : Freezable cannot be frozen.
<UserControl.Resources>
<Storyboard x:Key="OnMouseEnter1">
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(ContentControl.Content)" Storyboard.TargetName="contentControl">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource action_message_focus}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</UserControl.Resources>
<UserControl.Triggers>
<EventTrigger RoutedEvent="Mouse.MouseEnter" SourceName="ActionIconBox1">
<BeginStoryboard Storyboard="{StaticResource OnMouseEnter1}"/>
</EventTrigger>
</UserControl.Triggers>
I tried with the style triggers and it worked. Below is the style definition.
<ContentControl>
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Content" Value="{StaticResource action_message}"/>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Content" Value="{StaticResource action_message_focus}"/>
</Trigger>
</Style.Triggers>
</Style>
</ContentControl.Style>
</ContentControl>
From the Freezable Objects Overview page at MSDN:
A Freezable can't be frozen if any of the following are true:
•
It has animated or data bound properties.
•
It has properties set by a dynamic resource. (See the Resources Overview for more information about dynamic resources.)
•
It contains Freezable sub-objects that can't be frozen.
I'm guessing that it applies to your Canvas control because you have a Path object inside it that itself can't be frozen because of the DynaimcResource it uses.

Creating a search box using WPF

I'm trying to create a search box with the controls TextBox and ListBox.
When I'm on the TextBox starting to type an event handler GotFocus open the ListBox.
I want the ListBox to be closed when the TextBox not on focus. I tried to use the LostFocus event in the TextBox, but it didn't work.
In which event handler should I use? I didn't find a good example implements this mechanism.
Edit:
I have something like that:
<Canvas Name="m_MainCanvas" Grid.ColumnSpan="2" >
<Rectangle MouseDown="Canvas_MouseDown" Fill="White" Height="280" HorizontalAlignment="Left" Margin="256,12,0,0" x:Name="m_MainRectangle" RadiusX="0" RadiusY="0" Stroke="Black" StrokeThickness="3" VerticalAlignment="Top" Width="238" />
<TextBox Height="23" Margin="10,0,0,210" Name="m_SearchTextBox" VerticalAlignment="Bottom" BorderThickness="0.5" BorderBrush="#69000000" TextChanged="m_SearchTextBox_TextChanged" FontFamily="Kristen ITC" Text="" FontSize="14" FontWeight="Black" HorizontalAlignment="Left" Width="165" Canvas.Top="86" Canvas.Left="274" LostFocus="m_SearchTextBox_LostFocus"/>
<ListBox ItemTemplate="{DynamicResource ListBoxItemDataTemplate}" ItemsSource="{Binding}" Name="m_FriendsSearchList" Visibility="Hidden" Background="#FFBCEB85" Width="181" Height="193" Canvas.Left="283" Canvas.Top="118">
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<EventSetter Event="MouseDoubleClick" Handler="HandleDoubleClickItemToSelect" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
The MouseDown event in the Rectangle control is used to get the TextBox out of focus, but it isn't working.
something like:
<StackPanel>
<TextBox>
<TextBox.Triggers>
<EventTrigger RoutedEvent="GotFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
Storyboard.TargetName="lb"
Storyboard.TargetProperty="(ListBox.Opacity)"
To="1" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="LostFocus">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
Storyboard.TargetName="lb"
Storyboard.TargetProperty="(ListBox.Opacity)"
To="0" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</TextBox.Triggers>
</TextBox>
<ListBox x:Name="lb"
Opacity="0">
<ListBoxItem Content="A" />
<ListBoxItem Content="B" />
</ListBox>
</StackPanel>
However in the above approach the ListBox is still holding the space it resides in. if we instead toggle Visibility to Collapsed, every-time the ListBox becomes Visible other control's are going to start moving to accomodate that.
To avoid both these cases, such things are normally implemented via a Popup
<StackPanel>
<TextBox x:Name="tb" />
<Popup Width="{Binding RelativeSource={RelativeSource Self},
Path=PlacementTarget.ActualWidth}"
Placement="Bottom"
PlacementTarget="{Binding ElementName=tb}">
<Popup.Style>
<Style TargetType="{x:Type Popup}">
<Setter Property="IsOpen"
Value="False" />
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=tb,
Path=IsFocused}"
Value="True">
<Setter Property="IsOpen"
Value="True" />
</DataTrigger>
</Style.Triggers>
</Style>
</Popup.Style>
<ListBox>
<ListBoxItem Content="A" />
<ListBoxItem Content="B" />
</ListBox>
</Popup>
</StackPanel>
^^ You'll still see the same output however you no longer have any control's that have to change position due to the popup changing open / close states.
Update:
Download Link
Remember the Trigger is set based on the TextBox having / losing focus. IF you click somewhere that does not take focus, then you will not see the Popup(ListBox) disappear.

3d object not rendered

I have a WPF application that has a main window. In that I have a frame, the frame content is a page.
Now in page is 4 viewport3D that contain Viewport2DVisual3D and in that I have image element.
Problem : on some PCs my application runs well but on some PCs my application doesn't render viewport3d or it doesn't render the frame. Dunno but it doesn't show anything in main window.
The problem occurs on an Acer laptop Model.
Rendered :
Not Rendered :
EDIT:
This issue occurred again when I placed the frame in a grid. (I show this page in a frame, that frame is the main content of my window: when I place the frame in a grid it didn't show objects)
Seems This Occure on laptop with shared graphics
EDIT 2:
<Page x:Class="MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Loaded="Page_Loaded_1"
x:Name="myMainPage" FlowDirection="RightToLeft" >
<Page.Resources>
<Style TargetType="ContentControl" x:Key="MenuItemsStyle">
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate>
<Viewport3D VerticalAlignment="Stretch" HorizontalAlignment="Stretch" ClipToBounds="False">
<Viewport3D.Camera>
<PerspectiveCamera x:Name="myCam" FieldOfView="90" Position="{Binding ElementName=myMainWindow, Path=CameraHeight}" NearPlaneDistance="1" FarPlaneDistance="10"/>
</Viewport3D.Camera>
<ModelVisual3D>
<ModelVisual3D.Content>
<Model3DGroup>
<DirectionalLight Color="#FFFFFFFF" Direction="0,0,-1"/>
</Model3DGroup>
</ModelVisual3D.Content>
</ModelVisual3D>
<Viewport2DVisual3D x:Name="V2d3d">
<Viewport2DVisual3D.Transform>
<Transform3DGroup>
<RotateTransform3D >
<RotateTransform3D.Rotation>
<AxisAngleRotation3D Axis="0,1,0" Angle="0" x:Name="aar3D"/>
</RotateTransform3D.Rotation>
</RotateTransform3D>
</Transform3DGroup>
</Viewport2DVisual3D.Transform>
<Viewport2DVisual3D.Material>
<DiffuseMaterial Viewport2DVisual3D.IsVisualHostMaterial="True" Brush="White"/>
</Viewport2DVisual3D.Material>
<Viewport2DVisual3D.Geometry>
<MeshGeometry3D Positions="{Binding ElementName=myMainWindow, Path=MeshPosions}"
TextureCoordinates="0,0 0,1 1,1 1,0" TriangleIndices="0 1 2 0 2 3"/>
</Viewport2DVisual3D.Geometry>
<Border Name="mainBorder" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<Border.Style>
<Style TargetType="Border">
<Setter Property="BorderThickness" Value="1.2"/>
<Setter Property="Background" >
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" >
<Setter.Value>
<SolidColorBrush Color="Transparent"/>
</Setter.Value>
</Setter>
</Style>
</Border.Style>
<ContentPresenter VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
Content="{TemplateBinding ContentControl.Content}">
<ContentPresenter.Triggers>
<EventTrigger RoutedEvent="ContentPresenter.MouseLeftButtonDown">
// Axis Animation
</EventTrigger>
</ContentPresenter.Triggers>
</ContentPresenter>
</Border>
</Viewport2DVisual3D>
</Viewport3D>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<EventTrigger RoutedEvent="ContentControl.MouseLeftButtonDown" >
//Axis Animation
</EventTrigger>
<EventTrigger RoutedEvent="ContentControl.MouseEnter">
//ScaleAnimation
</EventTrigger>
<EventTrigger RoutedEvent="ContentControl.MouseLeave">
//ScaleAnimation
</EventTrigger>
</Style.Triggers>
</Style>
</Page.Resources>
<Page.Triggers>
<EventTrigger RoutedEvent="Loaded">
//Load Object Scale And Fade In
</EventTrigger>
</Page.Triggers>
<Grid Name="MainGrid">
<Canvas Name="MainCanvas" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" FlowDirection="LeftToRight">
<ContentControl Opacity="0" Name="MenuItem1" Style="{StaticResource MenuItemsStyle}"
MouseDown="MenuItem1_MouseDown" Panel.ZIndex="1" >
<Image Source="/IsargaranProject;component/Images/isargari.jpg"/>
<ContentControl.RenderTransform>
<ScaleTransform ScaleX="0.7" ScaleY="0.7" x:Name="MenuItem1ST"/>
</ContentControl.RenderTransform>
</ContentControl>
</Canvas>
</Grid>
</Page>
If you are using OPENGL or DirectX3D, then see that the laptop which is not rendering, will have some missing plugins like DirectX 3D wouldn't be installed or OpenGL you can try this two 3D Rendering tools for the same.. i had tried this in past i had made a Graph program it was having the same problem, but when i installed OPENGL & DirectX3D it was working fine!

Categories

Resources