Remodel simple WPF code to WinRT - c#

For four days i trying to rewmodel the following code to analogue in WinRT, but I can't. :/
The WinRT does not have DrawingImage, so I tried to proceed by analogy with the Path or Polyline, but I failed.
I'm sure, that if someone know WPF and WinRT this is not problem for him to remodel this code.
I think, that only problems are with DrawingImage and with triggering.
I know, that it's a lot of code, but i think, that problem is trivial, nevertheless i does not know how to solve this for four days. ;/
I would be very grateful for help with remodel this code.
<Window x:Class="HexagonGridTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:HexagonGridTest"
Title="Window1" Height="741.836" Width="697.351" Background="#FF232323">
<Window.Resources>
<DrawingImage x:Key="HexagonImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="#11AA11"
Geometry="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z">
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="10" LineJoin="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="HexagonHoverImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Khaki"
Geometry="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z">
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="10" LineJoin="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<DrawingImage x:Key="HexagonPressedImage">
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="Orange"
Geometry="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z">
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="10" LineJoin="Round"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
<Style x:Key="HexagonButtonStyle" TargetType="{x:Type Button}">
<Setter Property="Background" Value="Khaki"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Grid>
<Image x:Name="img" Source="{StaticResource HexagonImage}"/>
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="img" Property="Source" Value="{StaticResource HexagonHoverImage}"/>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="img" Property="Source" Value="{StaticResource HexagonPressedImage}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<local:HexagonGrid Rows="4" Columns="1" HexagonSideLength="40">
<local:HexagonGrid.Resources>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource HexagonButtonStyle}"/>
</local:HexagonGrid.Resources>
<Button Grid.Row="0" Grid.Column="2" Content="0,2"/>
<Button Grid.Row="0" Grid.Column="1" Content="0,1"/>
<Button Grid.Row="1" Grid.Column="2" Content="1,2"/>
</local:HexagonGrid>
</Grid>
</Window>
This class should be compatible with WinRT.
using System;
using System.Windows;
using System.Windows.Controls;
namespace HexagonGridTest
{
public class HexagonGrid : Grid
{
public static readonly DependencyProperty HexagonSideLengthProperty =
DependencyProperty.Register("HexagonSideLength", typeof(double), typeof(HexagonGrid), null);
public double HexagonSideLength
{
get { return (double)GetValue(HexagonSideLengthProperty); }
set { SetValue(HexagonSideLengthProperty, value); }
}
public static readonly DependencyProperty RowsProperty =
DependencyProperty.Register("Rows", typeof(int), typeof(HexagonGrid), new PropertyMetadata((int)1));
public int Rows
{
get { return (int)GetValue(RowsProperty); }
set { SetValue(RowsProperty, value); }
}
public static readonly DependencyProperty ColumnsProperty =
DependencyProperty.Register("Columns", typeof(int), typeof(HexagonGrid), new PropertyMetadata((int)1));
public int Columns
{
get { return (int)GetValue(ColumnsProperty); }
set { SetValue(ColumnsProperty, value); }
}
protected override Size MeasureOverride(Size constraint)
{
double side = HexagonSideLength;
double width = 2 * side;
double height = side * Math.Sqrt(3.0);
double colWidth = 0.75 * width;
double rowHeight = height;
Size availableChildSize = new Size(width, height);
foreach (FrameworkElement child in this.Children)
{
child.Measure(availableChildSize);
}
double totalHeight = Rows * rowHeight;
if (Columns > 1)
totalHeight += (0.5 * rowHeight);
double totalWidth = Columns + (0.5 * side);
Size totalSize = new Size(totalWidth, totalHeight);
return totalSize;
}
protected override Size ArrangeOverride(Size arrangeSize)
{
double side = HexagonSideLength;
double width = 2 * side;
double height = side * Math.Sqrt(3.0);
double colWidth = 0.75 * width;
double rowHeight = height;
Size childSize = new Size(width, height);
foreach (FrameworkElement child in this.Children)
{
int row = GetRow(child);
int col = GetColumn(child);
double left = col * colWidth;
double top = row * rowHeight;
bool isUnevenCol = (col % 2 != 0);
if (isUnevenCol)
top += (0.5 * rowHeight);
child.Arrange(new Rect(new Point(left, top), childSize));
}
return arrangeSize;
}
}
}
My Page Resources with Style code, which is incorrect, that is sure, but i can't correct that.
Don't throw any errors, just don't draw anything.
<Page.Resources>
<Path x:Key="HexagoPath"
Stroke="DarkGoldenRod"
StrokeThickness="7"
Fill="AliceBlue"
Data="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z" />
<Path x:Key="HexagoPathHover"
Stroke="DarkGoldenRod"
StrokeThickness="7"
Fill="Bisque"
Data="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z" />
<Path x:Key="HexagoPathPressed"
Stroke="DarkGoldenRod"
StrokeThickness="7"
Fill="Brown"
Data="M 250,0 L 750,0 L 1000,433 L 750,866 L 250,866 L 0,433 Z" />
<Style x:Key="HexagoPathStyle" TargetType="Button">
<Setter Property="MinWidth" Value="0"/>
<Setter Property="MinHeight" Value="0"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="Transparent">
<Path x:Name="PH" DataContext="{StaticResource HexagoPath}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPointerOverBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPointerOverForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Background" Storyboard.TargetName="Border">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedBackgroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground" Storyboard.TargetName="ContentPresenter">
<DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource ButtonPressedForegroundThemeBrush}"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Path>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Page.Resources>

Related

C# WPF How to keep Application responsive while adding many UI Elements to Stackpanel

I made an Application where I add many Grids to some Stackpanels in a for loop. My problem is that, while the for loop is loading my Application doesn´t respond and my Loadinganimation is freezed. How can I add the Grids to the Stackpanel without affecting the UI Thread, so my Loading Animation won´t freeze.
Thanks in Advance
Edit:
Grid creation Method:
public void GridExample()
{
for(int i = 0; i < 120; i++)
{
Grid Grid1 = new Grid();
Grid1.FlowDirection = FlowDirection.LeftToRight;
Grid1.Width = 200;
Grid1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Grid1.Margin = new Thickness(5, 20, 5, 20);
ColumnDefinition Grid1_col1 = new ColumnDefinition();
Grid1.ColumnDefinitions.Add(Grid1_col1);
RowDefinition Grid1_row1 = new RowDefinition();
RowDefinition Grid1_row2 = new RowDefinition();
RowDefinition Grid1_row3 = new RowDefinition();
RowDefinition Grid1_row4 = new RowDefinition();
Grid1.RowDefinitions.Add(Grid1_row1);
Grid1.RowDefinitions.Add(Grid1_row2);
Grid1.RowDefinitions.Add(Grid1_row3);
Grid1.RowDefinitions.Add(Grid1_row4);
Grid1_row1.Height = new GridLength(255);
Grid1_row2.Height = new GridLength(60);
Grid1_row3.Height = new GridLength(5);
Grid1_row4.Height = new GridLength(55);
//Adds Grid to HomePage
homepage1_mainstackpanel1.Children.Add(Grid1);
Image Image1 = new Image();
Image1.Stretch = Stretch.Fill;
Image1.Source = new BitmapImage(new Uri("Image.png"));
Grid.SetRow(Image1, 0);
Grid1.Children.Add(Image1);
Label Label1 = new Label();
Label1.Content = "Example Text";
Label1.FontSize = 15;
Label1.Foreground = new SolidColorBrush(Colors.White);
Label1.VerticalAlignment = VerticalAlignment.Center;
Label1.HorizontalAlignment = HorizontalAlignment.Center;
Grid.SetRow(Label1, 1);
Grid1.Children.Add(Label1);
Line Line1 = new Line();
Line1.X1 = 1;
Line1.StrokeThickness = 2;
Line1.Stroke = new SolidColorBrush(Color.FromArgb(255, (byte)51, (byte)51, (byte)51));
Line1.Stretch = Stretch.Fill;
Grid.SetRow(Line1, 2);
Grid1.Children.Add(Line1);
Button Button1 = new Button();
Button1.Content = "Play";
Button1.FontSize = 15;
Button1.Foreground = new SolidColorBrush(Colors.White);
Button1.Background = new SolidColorBrush(Color.FromArgb(255, (byte)33, (byte)33, (byte)33));
Button1.BorderThickness = new Thickness(0);
Button1.VerticalAlignment = VerticalAlignment.Center;
Button1.HorizontalAlignment = HorizontalAlignment.Center;
Button1.Click += new RoutedEventHandler((sender, e) =>
{
this.NavigationService.Navigate(new WatchPage1());
});
Grid1.Children.Add(Button1);
}
}
Loading Animation in HomePage:
public static Dispatcher mainthread_dispatcher = Dispatcher.CurrentDispatcher;
public HomePage1()
{
Loaded += Page_loaded;
InitializeComponent();
}
private void Page_loaded(object sender, RoutedEventArgs e)
{
using (LoadingAnimation loadanimation = new LoadingAnimation(GridExample))
{
loadanimation.ShowDialog();
}
}
LoadingAnimation.xaml:
<Window x:Class="Spaceflix_Desktop.LoadingAnimation"
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:local="clr-namespace:Spaceflix_Desktop"
mc:Ignorable="d"
Height="110" Width="90" Loaded="Animation_Loaded">
<Window.Resources>
<Storyboard x:Key="Storyboard1" RepeatBehavior="Forever">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse1">
<EasingColorKeyFrame KeyTime="0" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#B25B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse2">
<EasingColorKeyFrame KeyTime="0" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#FF5B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse3">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse4">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse5">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse6">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse7">
<EasingColorKeyFrame KeyTime="0" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#B25B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#005B5B5B"/>
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" Storyboard.TargetName="ellipse8">
<EasingColorKeyFrame KeyTime="0" Value="#7F5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.3" Value="#005B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:0.7" Value="sc#0, 0.104616486, 0.104616486, 0.104616486"/>
<EasingColorKeyFrame KeyTime="0:0:1" Value="#FF5B5B5B"/>
<EasingColorKeyFrame KeyTime="0:0:1.4" Value="#7F5B5B5B"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Window.Triggers>
<Border x:Name="Border" BorderBrush="#c62828" BorderThickness="2" Background="Black" Height="80" Width="80">
<Grid x:Name="maingrid" Background="Transparent">
<Ellipse x:Name="ellipse1" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 5, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse2" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 15, 15, 0" Height="15" VerticalAlignment="Top" Width="15"/>
<Ellipse x:Name="ellipse3" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 5, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse4" Fill="#FF5B5B5B" HorizontalAlignment="Right" Margin="0, 0, 15, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse5" Fill="#FF5B5B5B" HorizontalAlignment="Center" Margin="0, 0, 0, 5" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse6" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 0, 0, 15" Height="15" VerticalAlignment="Bottom" Width="15"/>
<Ellipse x:Name="ellipse7" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="5, 0, 0, 0" Height="15" VerticalAlignment="Center" Width="15"/>
<Ellipse x:Name="ellipse8" Fill="#FF5B5B5B" HorizontalAlignment="Left" Margin="15, 15, 0, 0" Height="15" VerticalAlignment="Top" Width="15"/>
</Grid>
</Border>
</Window>
LoadingAnimation.cs:
using System;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Threading;
using System.Windows.Threading;
using System.Windows.Media.Animation;
using System.Windows.Controls.Primitives;
using System.ComponentModel;
using System.Runtime.Remoting.Channels;
using System.Windows.Media.Media3D;
using System.Windows.Interop;
namespace Test_Application
{
/// <summary>
/// Interaktionslogik für LoadingAnimation.xaml
/// </summary>
public partial class LoadingAnimation : Window, IDisposable
{
public Action Worker { get; set; }
public LoadingAnimation (Action worker)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
}
public void Animation_Loaded(object sender, RoutedEventArgs e)
{
Task.Factory.StartNew(() => { }).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), TaskScheduler.FromCurrentSynchronizationContext()).ContinueWith(t => Dispatcher.Invoke(() => Close()));
}
public void Dispose()
{
}
}
}
I hope this Information are enough
after I didn't have time for this project for a long time, I've now dealt with it again and found a solution. I can't add the grids to the stack panels in a new task or thread but at least I can display the loading animation smoothly. Because the grids have to be added to the main thread, I ran the loading animation in a new thread. So I had to display it as a popup. This is the best solution I found.
Here is the Code from the HomePage:
var PositionWindow = (Window)Parent;
int CenterX = 8;
int CenterY = 1;
Point CenterPoints = new Point(PositionWindow.Left + CenterX + (PositionWindow.Width / 2), PositionWindow.Top + CenterY + (PositionWindow.Height / 2));
Thread LoadThread = new Thread(new ThreadStart(() => {
using (PopUpLoadingAnimation loadanimation = new PopUpLoadingAnimation(GridExample, CenterPoints, PositionWindow))
{
loadanimation.StartTask();
Dispatcher.Run();
}
}));
LoadThread.SetApartmentState(ApartmentState.STA);
LoadThread.Start();
I had to calculate the middle of the Window by myself to make the PopUp centered.
And here is the Code of the PopUpLoadingAnimation.cs:
public partial class PopUpLoadingAnimation : Popup
{
public Action Worker { get; set; }
private Point _PlacementPoints { get; set; }
private Window MainWindow { get; set; }
public PopUpLoadingAnimation (Action worker, Point PlacementPoints, Window mainthreadwindow)
{
InitializeComponent();
Worker = worker ?? throw new ArgumentNullException();
MainWindow = mainthreadwindow;
_PlacementPoints = PlacementPoints;
}
public void StartTask()
{
Task.Factory.StartNew(() => Dispatcher.Invoke(() =>
{
Storyboard animationboard = Resources["Storyboard1"] as Storyboard;
animationboard.Begin(maingrid);
LoadingPopup.Placement = PlacementMode.Center;
LoadingPopup.HorizontalOffset = _PlacementPoints.X;
LoadingPopup.VerticalOffset = _PlacementPoints.Y;
LoadingPopup.IsOpen = true;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = false);
})).ContinueWith(t => HomePage1.mainthread_dispatcher.Invoke(() => Worker()), HomePage1.mainthread_scheduler).ContinueWith(t => Dispatcher.Invoke(async () =>
{
LoadingPopup.IsOpen = false;
HomePage1.mainthread_dispatcher.Invoke(() => MainWindow.IsEnabled = true);
Dispatcher.InvokeShutdown();
}));
}
by the way thanks for the answers, unfortunately they did not help

Custom User Control Button Backgroundcolor changes on ShowDialog

I am writing a custom user control library in .NET 4.5.2 with WPF.
My custom Button behaves very strange and I am really desperate by now. First of all, here's the project GitHub
The Problem
Here is the MainWindow of a test-project with the custom Button
Click-Event Code
Window1 win1 = new Window1();
win1.ShowDialog();
XAML-Code
<Grid>
<Cosmos:CButton x:Name="B1"
C_BackgroundTheme="HKS41"
HorizontalAlignment="Left"
Margin="62,80,0,0"
VerticalAlignment="Top"
Width="117"
Content="ShowDialog"
Click="CButton_Click"/>
</Grid>
Nothing too special. Now I click the Button and the second Window opens as usually.
XAML-Code
<Grid>
<Cosmos:CButton C_BackgroundTheme="Red" HorizontalAlignment="Left" Margin="83,100,0,0" VerticalAlignment="Top" Width="75" Content="Test 2"/>
<Cosmos:CButton C_BackgroundTheme="HKS44" HorizontalAlignment="Left" Margin="83,63,0,0" VerticalAlignment="Top" Width="75" Content="Test"/>
</Grid>
The Button from which the ShowDialog goes out, changes its Backgroundcolor to the one of the last button in the XAML code. In this case the lighter blue (HSK44), not the red.
Code
This is the CS-Code of the Custom Button:
public class CButton : Button
{
public static readonly DependencyProperty BackgroundThemeProperty = DependencyProperty.Register("C_BackgroundTheme", typeof(Theme), typeof(CButton), new PropertyMetadata(new PropertyChangedCallback(BackgroundValueChanged)));
public static readonly DependencyProperty ForegroundThemeProperty = DependencyProperty.Register("C_ForegroundTheme", typeof(Theme), typeof(CButton), new PropertyMetadata(new PropertyChangedCallback(ForegroundValueChanged)));
public static bool Backgroundchanged = false;
private static string backcolor;
private static string Backcolor
{
get { return backcolor; }
set
{
backcolor = value;
Backgroundchanged = true;
}
}
static CButton()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(CButton), new FrameworkPropertyMetadata(typeof(CButton)));
}
public Theme C_BackgroundTheme
{
get
{
return (Theme)GetValue(BackgroundThemeProperty);
}
set
{
SetValue(BackgroundThemeProperty, value);
}
}
public Theme C_ForegroundTheme
{
get
{
return (Theme)GetValue(ForegroundThemeProperty);
}
set
{
SetValue(ForegroundThemeProperty, value);
}
}
private static void BackgroundValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (CButton)d;
Backcolor = GetColorString((Theme)e.NewValue);
control.Background = (SolidColorBrush)(new BrushConverter().ConvertFrom(Backcolor));
control.OpacityMask = (SolidColorBrush)(new BrushConverter().ConvertFrom(ChangeColorBrightness((Color)ColorConverter.ConvertFromString(Backcolor), (float)-0.3).ToString()));
}
private static void ForegroundValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (CButton)d;
control.Foreground = GetColorBrush((Theme)e.NewValue);
}
public static Color ChangeColorBrightness(Color color, float correctionFactor)
{
float red = (float)color.R;
float green = (float)color.G;
float blue = (float)color.B;
if (correctionFactor < 0)
{
correctionFactor = 1 + correctionFactor;
red *= correctionFactor;
green *= correctionFactor;
blue *= correctionFactor;
}
else
{
red = (255 - red) * correctionFactor + red;
green = (255 - green) * correctionFactor + green;
blue = (255 - blue) * correctionFactor + blue;
}
return Color.FromArgb(color.A, (byte)red, (byte)green, (byte)blue);
}
protected override void OnMouseEnter(MouseEventArgs e)
{
Backcolor = this.Background.ToString();
ColorAnimation colorChangeAnimation = new ColorAnimation
{
To = ChangeColorBrightness((Color)ColorConverter.ConvertFromString(Backcolor), (float)0.15),
Duration = new Duration(new TimeSpan(0, 0, 0, 0, 100))
};
PropertyPath colorTargetPath = new PropertyPath("(Background).(SolidColorBrush.Color)");
Storyboard CellBackgroundChangeStory = new Storyboard();
Storyboard.SetTarget(colorChangeAnimation, this);
Storyboard.SetTargetProperty(colorChangeAnimation, colorTargetPath);
CellBackgroundChangeStory.Children.Add(colorChangeAnimation);
CellBackgroundChangeStory.Begin();
}
protected override void OnMouseLeave(MouseEventArgs e)
{
ColorAnimation colorChangeAnimation = new ColorAnimation
{
To = (Color)ColorConverter.ConvertFromString(Backcolor),
Duration = new Duration(new TimeSpan(0, 0, 0, 0, 100))
};
PropertyPath colorTargetPath = new PropertyPath("(Background).(SolidColorBrush.Color)");
Storyboard CellBackgroundChangeStory = new Storyboard();
Storyboard.SetTarget(colorChangeAnimation, this);
Storyboard.SetTargetProperty(colorChangeAnimation, colorTargetPath);
CellBackgroundChangeStory.Children.Add(colorChangeAnimation);
CellBackgroundChangeStory.Begin();
}
protected override void OnClick()
{
Thread.Sleep(10);
base.OnClick();
}
}
And here is the ResourceDictionary
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Cosmos">
<Style TargetType="{x:Type local:CButton}">
<Setter Property="FontFamily" Value="/Cosmos;component/Fonts/#Circular Std Medium"/>
<Setter Property="Content" Value="CButton"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Top"/>
<Setter Property="SnapsToDevicePixels" Value="True"/>
<Setter Property="Foreground" Value="#FFEEEEEE"/>
<Setter Property="Background" Value="#FF111111"/>
<Setter Property="Height" Value="32"/>
<Setter Property="Width" Value="120"/>
<Setter Property="FontSize" Value="14"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<Border Name="outerborder"
BorderThickness="0,0,0,3"
BorderBrush="{TemplateBinding OpacityMask}"
CornerRadius="2"
Height="{TemplateBinding Height}">
<Border Name="outerbordertop"
BorderThickness="0,0,0,0"
BorderBrush="Transparent"
CornerRadius="2"
Height="{TemplateBinding Height}">
<Border Name="border"
BorderThickness="0,0,0,0"
CornerRadius="2"
Background="{TemplateBinding Background}"
VerticalAlignment="Stretch">
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" Margin="0,1,0,0"/>
</Border>
</Border>
</Border>
<Rectangle Fill="{TemplateBinding OpacityMask}" HorizontalAlignment="Left" VerticalAlignment="Top" Margin="0,3,0,0"/>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsPressed" Value="true">
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.07" FillBehavior="HoldEnd" Storyboard.TargetName="outerborder" Storyboard.TargetProperty="BorderThickness" To="0,0,0,0" />
<ThicknessAnimation Duration="0:0:0.07" FillBehavior="HoldEnd" Storyboard.TargetName="outerbordertop" Storyboard.TargetProperty="BorderThickness" To="0,3,0,0" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<ThicknessAnimation Duration="0:0:0.07" FillBehavior="HoldEnd" Storyboard.TargetName="outerborder" Storyboard.TargetProperty="BorderThickness" To="0,0,0,3" />
<ThicknessAnimation Duration="0:0:0.07" FillBehavior="HoldEnd" Storyboard.TargetName="outerbordertop" Storyboard.TargetProperty="BorderThickness" To="0,0,0,0" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Why does the Button behave like this? I am also happy about any tips related to the Code.

Constructing wpf in-code for Transform Group based on the xaml code

I am having problem in constructing the in-code program based on the given xaml code. Especially for the Transform Group part and the Trigger part.
<Window x:Class="newStackOverflow.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:newStackOverflow"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<Storyboard x:Key="Storyboard1">
<DoubleAnimationUsingKeyFrames
Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[3].(TranslateTransform.X)"
Storyboard.TargetName="rectangle">
<EasingDoubleKeyFrame KeyTime="0:0:10" Value="300"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Canvas x:Name="canvas" VerticalAlignment="Stretch" Background="Green">
<Rectangle x:Name="rectangle"
Fill="#FFF4F4F5" Stroke="Black"
Height="100" Width="100"
Canvas.Left="10" Canvas.Top="10"
RenderTransformOrigin="0.5,0.5">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1"/>
<TranslateTransform X="50" Y="20"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Canvas>
<Button Content="Button"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Padding="10 5" Margin="10" Grid.Row="1">
<Button.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
</Button.Triggers>
</Button>
</Grid>
Can you give any ideas in developing the in-code part?Thanks in advance!:D
these are my codes. When i tried the codes, it say that the s.Begin(rectangle) exception user unhandled.
public partial class MainWindow : Window
{
private Storyboard s;
public MainWindow()
{
InitializeComponent();
Button button = new Button();
button.Height = 28;
button.Width = 58;
button.HorizontalAlignment = HorizontalAlignment.Center;
button.VerticalAlignment = VerticalAlignment.Center;
button.Content = "Button";
button.Name = "button";
this.RegisterName(button.Name, button);
Rectangle rectangle = new Rectangle();
rectangle.Width = 100;
rectangle.Height = 100;
rectangle.Fill = new SolidColorBrush(Colors.White);
rectangle.Stroke = new SolidColorBrush(Colors.Black);
Canvas.SetLeft(rectangle, 10);
Canvas.SetTop(rectangle,10);
canvas1.Children.Add(rectangle);
rectangle.Name = "rectangle";
TranslateTransform tt = new TranslateTransform();
ScaleTransform st = new ScaleTransform();
TransformGroup tg = new TransformGroup();
tg.Children.Add(tt);
tg.Children.Add(st);
button.RenderTransform = tg;
Duration duration = new Duration(TimeSpan.FromMilliseconds(10));
DoubleAnimationUsingKeyFrames myDoubleAnim = new DoubleAnimationUsingKeyFrames();
EasingDoubleKeyFrame myDoubleKey = new EasingDoubleKeyFrame();
Storyboard s = new Storyboard();
Storyboard.SetTargetName(myDoubleAnim, button.Name);
Storyboard.SetTargetProperty(myDoubleAnim, new PropertyPath("RenderTransform.Children[3].Y"));
myDoubleKey.KeyTime = KeyTime.FromPercent(1);
myDoubleKey.Value = 300;
myDoubleAnim.KeyFrames.Add(myDoubleKey);
s.Children.Add(myDoubleAnim);
s.Begin(rectangle);
//button.Loaded += new RoutedEventHandler(buttonLoaded);
}

Sorting a paged WPF ListView will sort only the items on current page

I have a listView with pages, and I try to sort it on column header click, but the problem is that it will sort only the items on the current page.I want the sorter to sort all the items and to display the items on pages in the right order. Example: now if I have 5,3,1 on page 1 and 2,6,4 on page 2 it will show 1,3,5 on page 1 and 2,4,6 on page2, and it needs to be 1,2,3 on page1 and 4,5,6 on page 2.
How I do it? This is the code I use:
CollectionViewSource view = new CollectionViewSource();
ObservableCollection<Server> Source = new ObservableCollection<Server>();
int currentPageIndex = 0;
int itemPerPage = 13;
int totalPage = 0;
//populating the listview
public void refreshList()
{
int itemcount = 0;
foreach (string id in server_id)
{
if (id != null && id != "")
{
Source.Add(new Server
{
ID = Int32.Parse(id),
NAME = server_name[Int32.Parse(id)],
PING = 0
});
itemcount++;
}
}
totalPage = itemcount / itemPerPage;
if (itemcount % itemPerPage != 0)
{
totalPage += 1;
}
view.Source = Source;
view.Filter += new FilterEventHandler(view_Filter);
listView1.DataContext = view;
}
//Paging
private void ShowCurrentPageIndex()
{
this.next.Content = (currentPageIndex + 1).ToString();
}
void view_Filter(object sender, FilterEventArgs e)
{
int index = Source.IndexOf((Server)e.Item);
if (index >= itemPerPage * currentPageIndex && index < itemPerPage * (currentPageIndex + 1))
{
e.Accepted = true;
}
else
{
e.Accepted = false;
}
}
private void btnPrev_Click(object sender, RoutedEventArgs e)
{
// Display previous page
if (currentPageIndex > 0)
{
currentPageIndex--;
view.View.Refresh();
}
ShowCurrentPageIndex();
}
private void btnNext_Click(object sender, RoutedEventArgs e)
{
// Display next page
if (currentPageIndex < totalPage - 1)
{
currentPageIndex++;
view.View.Refresh();
}
ShowCurrentPageIndex();
}
//Sorting
GridViewColumnHeader _lastHeaderClicked = null;
ListSortDirection _lastDirection = ListSortDirection.Ascending;
void GridViewColumnHeaderClickedHandler(object sender, RoutedEventArgs e)
{
GridViewColumnHeader headerClicked = e.OriginalSource as GridViewColumnHeader;
ListSortDirection direction;
if (headerClicked != null)
{
if (headerClicked != _lastHeaderClicked)
{
direction = ListSortDirection.Ascending;
}
else
{
if (_lastDirection == ListSortDirection.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
direction = ListSortDirection.Ascending;
}
}
string header = headerClicked.Column.Header as string;
Sort(header, direction);
_lastHeaderClicked = headerClicked;
_lastDirection = direction;
}
}
private void Sort(string sortBy, ListSortDirection direction)
{
var sortProperty = typeof(Server).GetProperty(sortBy);
if (direction == ListSortDirection.Ascending)
{
Source = new ObservableCollection<Server>(Source.OrderBy(s => sortProperty.GetValue(s)));
}
else
{
Source = new ObservableCollection<Server>(Source.OrderByDescending(s => sortProperty.GetValue(s)));
}
view.Source = Source;
view.View.Refresh();
}
ListView XAML:
<ListView Name="listView1" ItemsSource="{Binding}" ItemContainerStyle="{StaticResource LVitem}" BorderBrush="{x:Null}" Height="502" Margin="10,130,10,0" FontSize="20" GridViewColumnHeader.Click="GridViewColumnHeaderClickedHandler" FontFamily="/WpfApplication2;component/Resources/#Purista SemiBold" Background="#66181F2C" BorderThickness="1.000001" ScrollViewer.HorizontalScrollBarVisibility="Hidden" ScrollViewer.VerticalScrollBarVisibility="Hidden" >
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource ColumnHeader}" >
<GridViewColumn Header=" ID" Width="0" DisplayMemberBinding="{Binding ID}" />
<GridViewColumn Header=" NAME" Width="500" DisplayMemberBinding="{Binding NAME}" />
<GridViewColumn Header=" PING" Width="100" DisplayMemberBinding="{Binding PING}" />
</GridView>
</ListView.View>
</ListView>
<Button x:Name="next" Content="Next" Margin="1179,0,0,0" Click="btnNext_Click"/>
<Button x:Name="prev" Content="Prev" Margin="1179,0,0,0" Click="btnPrev_Click"/>
and this is the style used for listview:
<Style x:Key="LVitem" TargetType="{x:Type ListViewItem}">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#663F5768" Offset="0"/>
<GradientStop Color="#992E4051" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="20"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListViewItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="0,1,0,1" Background="{TemplateBinding Background}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition MaxHeight="7"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle x:Name="UpperHighlight" Fill="#FFE3F7FF" Visibility="Collapsed"/>
<Border Padding="{TemplateBinding Padding}" Grid.RowSpan="2">
<GridViewRowPresenter x:Name="Content" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0,0,0,1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#66597B93" Offset="0"/>
<GradientStop Color="#99364B5F" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#FFDADADA" Offset="1"/>
<GradientStop Color="White" Offset="0"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="BorderBrush" Value="{x:Null}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Because of the way you are filtering the items you have to sort your Source collection instead of the items.
private void Sort(string sortBy, ListSortDirection direction)
{
var sortProperty = typeof(Server).GetProperty(sortBy);
if(sortProperty == null) return;
if (direction == ListSortDirection.Ascending)
{
Source = new ObservableCollection<Server>(Source.OrderBy(s => sortProperty.GetValue(s, null)));
}
else
{
Source = new ObservableCollection<Server>(Source.OrderByDescending(s => sortProperty.GetValue(s, null)));
}
view.Source = Source;
view.View.Refresh();
}

Set selection to view box

Hello I have some buttons randomly assigned in my WPF application like so:
partial class Window1
{
private void button3_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("action 3");
}
void button2Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("action 2");
}
void button1Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("action 1");
}
public Window1()
{
this.InitializeComponent();
populateButtons();
}
public void populateButtons()
{
double xPos;
double yPos;
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = 100;
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(250);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Click += routedEventHandler;
LayoutRoot.Children.Add(foo);
}
}
}
}
I set the area in which to populate the buttons like so:
int xPos;
int yPos;
xPos = ranNum.Next(239);
yPos = ranNum.Next(307);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
What I would prefer to do now is set this area with a view box named viewbox1 (original eh!) ;)
Is there a way to do this in the code behind?
XAML:
<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xml:lang="en-US"
x:Class="DynamicButtons.Window1"
x:Name="Window"
Title="Dynamic Buttons"
WindowState="Normal" WindowStyle="None" AllowsTransparency="True" Background="Transparent"
Width="840" Height="600" Icon="shape_group.png">
<Window.Resources>
<Style x:Key="CurvedButton" BasedOn="{x:Null}" TargetType="{x:Type Button}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<ControlTemplate.Resources>
<Storyboard x:Key="OnMouseMove1">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00" Value="#FFFFFFFF"/>
<SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#7CE1DBDB"/>
</ColorAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="1"/>
<SplineDoubleKeyFrame KeyTime="00:00:00.3000000" Value="1.66"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnMouseLeave1">
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleX)">
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[0].(ScaleTransform.ScaleY)">
<SplineDoubleKeyFrame KeyTime="00:00:00.8000000" Value="1.78"/>
<SplineDoubleKeyFrame KeyTime="00:00:01" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="OnClick1">
<ColorAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)">
<SplineColorKeyFrame KeyTime="00:00:00.2000000" Value="#FFFFFFFF"/>
<SplineColorKeyFrame KeyTime="00:00:00.3000000" Value="#BFA0D1E2"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Rectangle RenderTransformOrigin="1,1" Fill="#3FFFFFFF" Stroke="{x:Null}" RadiusX="11" RadiusY="11" x:Name="rectangle">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleX="1" ScaleY="1"/>
<SkewTransform AngleX="0" AngleY="0"/>
<RotateTransform Angle="0"/>
<TranslateTransform X="0" Y="0"/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" RecognizesAccessKey="True"/>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="ButtonBase.Click">
<BeginStoryboard x:Name="OnClick1_BeginStoryboard" Storyboard="{StaticResource OnClick1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="Mouse.MouseLeave">
<BeginStoryboard x:Name="OnMouseLeave1_BeginStoryboard" Storyboard="{StaticResource OnMouseLeave1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
<EventTrigger RoutedEvent="Mouse.MouseEnter">
<BeginStoryboard x:Name="OnMouseMove1_BeginStoryboard" Storyboard="{StaticResource OnMouseMove1}"/>
</EventTrigger>
<Trigger Property="IsFocused" Value="True"/>
<Trigger Property="IsDefaulted" Value="True"/>
<Trigger Property="IsMouseOver" Value="True"/>
<Trigger Property="IsPressed" Value="True"/>
<Trigger Property="IsEnabled" Value="False"/>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush EndPoint="0,1" StartPoint="0,0">
<GradientStop Color="#FFF3F3F3" Offset="0"/>
<GradientStop Color="#FFEBEBEB" Offset="0.5"/>
<GradientStop Color="#FFDDDDDD" Offset="0.5"/>
<GradientStop Color="#E1CDCDCD" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Window.Triggers>
<EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
</Window.Triggers>
<Grid x:Name="LayoutRoot">
<Grid Name="MainLayoutGrid" Background="#2b2b2b">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="4" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="4" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="4" />
<RowDefinition Height="25" />
<RowDefinition Height="*" />
<RowDefinition Height="4" />
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1" Name="TitleGrid">
<Grid.RowDefinitions>
<RowDefinition Height="2"/>
<RowDefinition Height="*"/>
<RowDefinition Height="4"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Row="1" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="4"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Image Grid.Column="0" Name="ImageIcon" Stretch="Uniform"/>
<TextBlock Grid.Column="2" Name="Titleblk" Foreground="White">Wanna be Title</TextBlock>
</Grid>
<Grid Grid.Row="0" Grid.Column="2" Grid.RowSpan="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="25"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Name="btnMin" Grid.Column="1" Grid.ColumnSpan="2" Margin="8,4,42,-4">
<Button.RenderTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8"></ScaleTransform>
</Button.RenderTransform>
<Button.Clip>
<RectangleGeometry RadiusX="1000" RadiusY="1000" Rect="0,0,18,20" />
</Button.Clip>
</Button>
<Button Name="btnMax" Grid.Column="2" Margin="2,4,23,-4">
<Button.RenderTransform>
<ScaleTransform ScaleX="0.8" ScaleY="0.8"></ScaleTransform>
</Button.RenderTransform>
<Button.Clip>
<RectangleGeometry RadiusX="1000" RadiusY="1000" Rect="0,0,18,20" />
</Button.Clip>
</Button>
<Button Name="btnClose" Grid.Column="2" Margin="24,0,6,0" BorderBrush="#00000000" BorderThickness="0" ClickMode="Press" Foreground="#00000000" HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" OpacityMask="#82F8F8F8" VerticalAlignment="Stretch" VerticalContentAlignment="Center">
<Button.Clip>
<RectangleGeometry RadiusX="1000" RadiusY="1000" Rect="0,0,20,20" />
</Button.Clip>
</Button>
</Grid>
</Grid>
<Grid Grid.Column="1" Grid.Row="2">
<Grid.Background>
<LinearGradientBrush EndPoint="0.484,0.543" StartPoint="0.478,0.009">
<GradientStop Color="Gray" Offset="1"/>
<GradientStop Color="DarkGray" Offset="0"/>
</LinearGradientBrush>
</Grid.Background>
<UniformGrid>
<Viewbox Height="364" Name="viewbox1" Width="363" VerticalAlignment="Stretch" Margin="6,0,441,164" />
</UniformGrid>
</Grid>
</Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!--<Canvas Height="284" HorizontalAlignment="Left" Margin="457,66,0,0" Name="canvas1" VerticalAlignment="Top" Width="300" />-->
</Grid>
</Window>
Full Code:
namespace DynamicButtons
{
partial class Window1
{
void button3_Click(object sender, RoutedEventArgs e)
{
if (e.RoutedEvent == FrameworkElement.LoadedEvent)
{
ToolTip t = new ToolTip();
t.Content = "Something helpful";
((Button)sender).ToolTip = t;
((Button)sender).Content = "Hello";
return;
}
MessageBox.Show("Hello you punk");
}
void button2Click(object sender, RoutedEventArgs e)
{
//ToolTip t = new ToolTip();
//t.Content = "Something helpful";
//((Button)sender).ToolTip = t;
//MessageBox.Show("action 2");
}
void button1Click(object sender, RoutedEventArgs e)
{
//ToolTip t = new ToolTip();
//t.Content = "Something helpful";
//((Button)sender).ToolTip = t;
////Button b = new Button();
//((Button)sender).Content = "Hello";
////b.ToolTip = t;
//MessageBox.Show("action 1");
}
public Window1()
{
this.InitializeComponent();
populateButtons();
}
public void populateButtons()
{
double xPos;
double yPos;
UniformGrid grid = new UniformGrid();
Viewbox viewBox = new Viewbox();
viewBox.Name = "viewbox1";
viewBox.Stretch = Stretch.Fill;
viewBox.Child = grid;
LayoutRoot.Children.Add(viewBox);
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = 100;
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(100);
yPos = ranNum.Next(150);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Click += routedEventHandler;
foo.Loaded += routedEventHandler;
grid.Children.Add(foo);
}
}
To add the buttons to a ViewBox you can just do this:
public void populateButtons()
{
double xPos;
double yPos;
UniformGrid grid = new UniformGrid();
viewbox1.Child = grid;
Random ranNum = new Random();
foreach (var routedEventHandler in new RoutedEventHandler[] { button1Click, button2Click, button3_Click })
{
Button foo = new Button();
Style buttonStyle = Window.Resources["CurvedButton"] as Style;
int sizeValue = 100;
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(200);
yPos = ranNum.Next(250);
foo.HorizontalAlignment = HorizontalAlignment.Left;
foo.VerticalAlignment = VerticalAlignment.Top;
foo.Margin = new Thickness(xPos, yPos, 0, 0);
foo.Style = buttonStyle;
foo.Click += routedEventHandler;
grid.Children.Add(foo);
}
}
What is your reasoning for using a Viewbox? Is it for stretch and scale reasons?
I recommend using a Canvas and then you can set your Canvas.Left and Canvas.Top values similarly to how you set xPos and yPos.
Then if you wish to have the stretch / scale features of the Viewbox, you could put the Canvas you created as the child of the Viewbox.
UPDATE: to get the ActualHeight and ActualWidth values of the canvas during runtime you can add an event handler for SizeChanged (easy to do within the XAML but not too hard within code) to handle the change in height/width value during runtime. Here's the code solution:
bool initialized = false; // Should be located in class definition for your window
// ex. within "public partial class WindowName : Window
canvas.SizeChanged += new SizeChangedEventHandler(canvas_SizeChanged);
// Can be located in constructor for window
// ie. public MainWindow() { /* put it right here */ }
then the definition for the event handler can be as follows: (this only creates one button but would work with your for loop.)
Location update This definition below can be located within the class def for your window, but below the definition for the boolean variable "initialized". (ex. w/in "public partial class WindowName : Window")
private void canvas_SizeChanged(object sender, SizeChangedEventArgs e)
{
if (initialized == false) // so this only happens once.
{
int sizeValue = 100;
Random ranNum = new Random();
int modHeight = System.Convert.ToInt32(canvas.ActualHeight)-sizeValue;
int modWidth = System.Convert.ToInt32(canvas.ActualWidth)-sizeValue;
Button foo = new Button();
canvas.Children.Add(foo);
foo.Width = sizeValue;
foo.Height = sizeValue;
xPos = ranNum.Next(239) % modWidth;
yPos = ranNum.Next(307) % modHeight
Canvas.SetLeft(foo, xPos);
Canvas.SetTop(foo, yPos);
initialized = true;
}
}
Or, if you know what size your canvas is going to be you can just manually set modHeight and modWidth to the pixel value of your choice and not have to deal with the event handler.

Categories

Resources