I have a WPF Canvas with a TextBlock and an Image on it. The text is animated, but it doesn't look smooth. I tried many combinations of different FPS-Settings and durations but it won't get better.
I also want to let the text fade-in/out at the start and ending. But I found no methods to do so.
At the moment it looks like that:
How can I get the animation smoothly? How can I fade it in/out smoothly?
Before you ask, I need to show the Window invisible because I use the WpfAppBar and that component needs an HWND.
Here is the canvas xaml:
<Canvas x:Name="canMain" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<Border x:Name="boLogo" Panel.ZIndex="2" Height="40" Background="Gray" Canvas.Left="0" Canvas.Top="-20">
<Image Height="39" Width="auto" Margin="5, 0, 5, 0" Source="pack://siteoforigin:,,,/Resources/Logo.png" />
</Border>
<TextBlock x:Name="tbInfo" Panel.ZIndex="1" Visibility="Hidden" RenderOptions.BitmapScalingMode="NearestNeighbor" FontSize="32" TextOptions.TextFormattingMode="Display" TextOptions.TextRenderingMode="ClearType" FontFamily="Arial" FontWeight="Bold" Padding="5" HorizontalAlignment="Stretch" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform x:Name="AnimatedTranslateTransform" X="0" Y="0" />
</TextBlock.RenderTransform>
</TextBlock>
</Canvas>
And the code to animate the text:
public void ShowWindow(Brush fontColor, Brush backgroundColor, string str) {
var helper = new WindowInteropHelper(this);
helper.EnsureHandle();
tbInfo.Foreground = fontColor;
this.Background = backgroundColor;
tbInfo.Text = str;
this.Height = 39;
this.Width = SystemParameters.WorkArea.Width;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width;
ShowWindowInvisible();
WpfAppBar.AppBarFunctions.SetAppBar(this, WpfAppBar.ABEdge.Top);
Visibility = Visibility.Visible;
int duration = 10 + str.Length / 5;
TextMarquee(duration);
}
private void TextMarquee(int duration)
{
Timeline.DesiredFrameRateProperty.OverrideMetadata(
typeof(Timeline),
new FrameworkPropertyMetadata { DefaultValue = 60 }
);
double height = canMain.ActualHeight - tbInfo.ActualHeight;
tbInfo.Margin = new Thickness(0, height / 2, 0, 0);
DoubleAnimation doubleAnimation = new DoubleAnimation();
doubleAnimation.From = canMain.ActualWidth;
doubleAnimation.To = tbInfo.ActualWidth *-1;
doubleAnimation.RepeatBehavior = RepeatBehavior.Forever;
doubleAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration));
tbInfo.BeginAnimation(Canvas.LeftProperty, doubleAnimation);
tbInfo.Visibility = Visibility.Visible;
}
private void ShowWindowInvisible()
{
var width = Width;
var height = Height;
var windowStyle = WindowStyle;
var showInTaskbar = ShowInTaskbar;
var showActivated = ShowActivated;
Width = 0;
Height = 0;
WindowStyle = WindowStyle.None;
ShowInTaskbar = false;
ShowActivated = false;
Show();
Visibility = Visibility.Hidden;
Width = width;
Height = height;
WindowStyle = windowStyle;
ShowInTaskbar = showInTaskbar;
ShowActivated = showActivated;
}
I created app in Windows Phone 8.1(universal). I need to create a dynamic field of the buttons. This is my example xaml:
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid x:Name="_root"
Grid.Row="1"
Margin="10" />
This is my code:
_root.Children.Clear();
_root.ColumnDefinitions.Clear();
Size = 5;
for (int i = 0; i < Size; i++)
{
_root.ColumnDefinitions.Add(new ColumnDefinition
{
Width = new GridLength(1, GridUnitType.Star)
});
}
for (int column = 0; column < Size; column++)
{
Button btnTemp = new Button();
btnTemp.Visibility = Visibility.Visible;
btnTemp.VerticalAlignment = VerticalAlignment.Stretch;
btnTemp.HorizontalAlignment = HorizontalAlignment.Stretch;
btnTemp.HorizontalContentAlignment = HorizontalAlignment.Center;
btnTemp.VerticalContentAlignment = VerticalAlignment.Center;
btnTemp.BorderBrush = new SolidColorBrush(Colors.Blue);
btnTemp.Content = column;
Grid.SetColumn(btnTemp, column);
Grid.SetRow(btnTemp, 0);
_root.Children.Add(btnTemp);
}
It is my result:
If I used :
Width = new GridLength(1, GridUnitType.Auto)
I get result:
I need to fix these bugs:
1.Align text to the center of the button.
Do not see the right border of the button "4".Button "4" other widely.
Fix in your case is quite easy - just define MinWidth of created button as 0 (default has some value).
btnTemp.MinWidth = 0;
I think it should help.
Nevertheless, in your case I wouldn't add buttons to grid, I would probably define ItemsPanel and suitable ItemsTemplate with Button, then bind to a collection.
I'm new to Windows Phone programming. I want to create a gridview like the following:
I've done the <DataTemplate>, so I've already done the items and their buttons. But I can't set 2 columns for the grid using MaximumRowsOrColumns, because it limits my grid with only 2 rows (can be ilimited rows, but I need to have only 2 columns).
Coding as below was the closest I made:
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical" MaximumRowsOrColumns="2"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
EDIT: added <DataTemplate>code:
<DataTemplate x:Key="gridClassItem">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="14.96"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="14.96" />
</Grid.ColumnDefinitions>
<Button x:Name="btnItem" Grid.Row="0" Grid.Column="0"
BorderThickness="0 0 0 2" Opacity="100"
Height="70.4" Width="174.24"
Background="#FF6B33"
Click="btnItem_OnClick">
<TextBlock x:Name="txtItem" FontSize="38" Foreground="#5B1F08" Opacity="100" Margin="0" Text="{Binding Name}" TextAlignment="Center"/>
</Button>
<Grid Grid.Row="1" Grid.Column="0" Margin="0, -8, 0, 0" Height="52.8">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="86.24"/>
<ColumnDefinition Width="86.24"/>
</Grid.ColumnDefinitions>
<Button x:Name="btn1" Click="btn1_OnClick"
Grid.Row="0" Grid.Column="0"
BorderBrush="#FFFFFF" BorderThickness="0 0 1.76 0"
Margin="-10, -15, 0, 0"
DataContext="{Binding}">
<Button.Background>
<ImageBrush ImageSource="\Assets\bt1.png" Stretch="UniformToFill"/>
</Button.Background>
</Button>
<Button x:Name="btn2" Click="btn2_OnClick"
Grid.Row="0" Grid.Column="1"
BorderBrush="#FFFFFF" BorderThickness="1.76 0 0 0"
Margin="0, -15, -2.5, 0"
DataContext="{Binding}">
<Button.Background>
<ImageBrush ImageSource="\Assets\bt2.png" Stretch="UniformToFill"/>
</Button.Background>
</Button>
</Grid>
<Rectangle Grid.Row="2" Grid.Column="1" Fill="#FFFFFF" Margin="0"/>
</Grid>
</DataTemplate>
Any suggestions?
By the way, any idea how could i change the GridViewItem's background color? I was thinking about a geometric series, like the first item will be orange, the followings - always counting by two - will be green and then orange again. But I don't know how to implement it.
Well, since I couldn't find a way to do it using XAML, I did it at C#. Below is my solution, if someone need something looked like:
enum GridItemColor
{
NONE,
BLUE,
RED
};
//Some event to populate a list
...
myGrid.Items.Clear();
GridItemColor lastColor = GridItemColor.NONE;
foreach (MyModel item in myList)
{
if (lastColor == GridItemColor.NONE || lastColor == GridItemColor.BLUE)
{
myGrid.Items.Add(FormatGridViewItem(item, GridItemColor.RED));
lastColor = GridItemColor.RED;
}
else if (lastColor == GridItemColor.RED)
{
myGrid.Items.Add(FormatGridViewItem(item, GridItemColor.BLUE));
lastColor = GridItemColor.BLUE;
}
}
...
private Grid FormatGridViewItem(MyModel currentItem, GridItemColor itemColor)
{
Grid gridItem = new Grid();
#region Grid Item Row Definition and GridItem Setup
RowDefinition itemRowDef = new RowDefinition();
RowDefinition minorButtonRowDef = new RowDefinition();
itemRowDef.Height = new GridLength(72);
minorButtonRowDef.Height = new GridLength(49);
gridItem.RowDefinitions.Add(classPlanRowDef);
gridItem.RowDefinitions.Add(minorButtonRowDef);
gridItem.MaxWidth = 196;
gridItem.Width = 196;
gridItem.Margin = new Thickness(0, 0, 24, 24);
#endregion
#region Button Item
Button btnItem = new Button();
btnItem.BorderThickness = new Thickness(0);
btnItem.Margin = new Thickness(-3, 0, 0, 0);
btnItem.Opacity = 100;
btnItem.MaxWidth = 203;
btnItem.MinWidth = 203;
btnItem.Height = 78;
btnItem.DataContext = currentItem;
if (itemColor == GridItemColor.RED)
btnItem.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 107, 51));
else
btnItem.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 23, 229, 192));
btnItem.Click += btnItem_Click;
TextBlock txtItem = new TextBlock();
txtItem.FontSize = 40;
if (itemColor == GridItemColor.RED)
txtItem.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 91, 31, 8));
else
txtItem.Foreground = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 3, 97, 80));
txtItem.Opacity = 100;
txtItem.TextAlignment = TextAlignment.Center;
txtItem.Text = currentItem.Name;
txtItem.TextTrimming = TextTrimming.CharacterEllipsis;
btnItem.Content = txtItem;
gridItem.Children.Add(btnItem);
Grid.SetRow(btnItem, 0);
#endregion
#region Grid Minor Buttons Row
Grid minorButtonsRow = new Grid();
minorButtonsRow.Margin = new Thickness(0);
if (itemColor == GridItemColor.RED)
minorButtonsRow.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 107, 51));
else
minorButtonsRow.Background = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 23, 229, 192));
ColumnDefinition btnOneColumnDef = new ColumnDefinition();
ColumnDefinition btnTwoColumnDef = new ColumnDefinition();
btnOneColumnDef.Width = new GridLength(98);
btnTwoColumnDef.Width = new GridLength(98);
minorButtonsRow.ColumnDefinitions.Add(btnOneColumnDef);
minorButtonsRow.ColumnDefinitions.Add(btnTwoColumnDef);
// Button One
Button btnOne = new Button();
btnOne.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 255, 255));
btnOne.BorderThickness = new Thickness(0);
btnOne.MinWidth = 97;
btnOne.MaxWidth = 97;
btnOne.MinHeight = 48;
btnOne.MaxHeight = 48;
btnOne.Margin = new Thickness(0, 0, 1, 0);
btnOne.DataContext = currentItem;
btnOne.Click += btnOne_Click;
ImageBrush imgOne = new ImageBrush();
BitmapImage bitImg;
if (itemColor == GridItemColor.RED)
{
bitImg = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btOneRED.png", UriKind.RelativeOrAbsolute));
btnOne.Style = (Style)this.Resources["btnOneRedStyle"];
}
else
{
bitImg = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btOneBLUE.png", UriKind.RelativeOrAbsolute));
btnOne.Style = (Style)this.Resources["btnOneBlueStyle"];
}
imgOne.ImageSource = bitImg;
imgOne.Stretch = Stretch.UniformToFill;
btnOne.Background = imgOne;
minorButtonsRow.Children.Add(btnOne);
Grid.SetRow(btnOne, 0);
Grid.SetColumn(btnOne, 0);
// END Button One
// Button Two
Button btnTwo = new Button();
btnTwo.BorderBrush = new SolidColorBrush(Windows.UI.Color.FromArgb(0xFF, 255, 255, 255));
btnTwo.BorderThickness = new Thickness(0);
btnTwo.MinWidth = 97;
btnTwo.MaxWidth = 97;
btnTwo.MinHeight = 48;
btnTwo.MaxHeight = 48;
btnTwo.Margin = new Thickness(1, 0, 0, 0);
btnTwo.DataContext = currentItem;
btnTwo.Click += btnTwo_Click;
ImageBrush imgTwo = new ImageBrush();
BitmapImage bitImgTwo;
if (itemColor == GridItemColor.RED)
{
bitImgTwo = new BitmapImage(new Uri("ms-appx:/Assets/Icons/btTwoRED.png", UriKind.RelativeOrAbsolute));
btnTwo.Style = (Style)this.Resources["btnTwoRedStyle"];
}
else
{
bitImgTwo = new BitmapImage(new Uri("ms-appx:/Assets/Icons/bt_AgendaVerde.png", UriKind.RelativeOrAbsolute));
btnTwo.Style = (Style)this.Resources["btnTwoBlueStyle"];
}
imgTwo.ImageSource = bitImgTwo;
imgTwo.Stretch = Stretch.UniformToFill;
btnTwo.Background = imgTwo;
minorButtonsRow.Children.Add(btnTwo);
Grid.SetRow(btnTwo, 0);
Grid.SetColumn(btnTwo, 1);
gridItem.Children.Add(minorButtonsRow);
Grid.SetRow(minorButtonsRow, 1);
Grid.SetColumn(minorButtonsRow, 0);
// END Button Two
#endregion
return gridItem;
}
If you have DataTemplate done correctly, then you don't need the ItemsPanel template. Can you show the code for DataTemplate? Because with it you can do pretty much everything.
For the colors. Declare brushes on your ViewModel and then assign it to your classes.Then just bind the Background. You only need one for each color.
Color binding: say you have SolidColorBrush property on your model named BgBrush. All you need to do is declare Background property on your control (i.e. grid) as "{Binding BgBrush}"
I would like to create a scratch card effect on the Windows Phone. However my current solution seem sluggish and the scratch effect look weird(refer to the screenshot below). The experience is very poor as compared to those that i had seen on iOS.
Would appreciate if someone could guide me toward it. Below are my current code.
<Grid Width="Auto" Height="Auto" Background="Black">
<Viewbox Margin="0" HorizontalAlignment="Center" VerticalAlignment="Center">
<Grid Height="60" Width="60" Background="White">
<InkPresenter x:Name="inkP" Width="60" Height="60">
<InkPresenter.Background>
<ImageBrush Stretch="Fill" ImageSource="/Assets/image.png"/>
</InkPresenter.Background>
<Grid Height="60" Width="60">
<TextBlock x:Name="lblsecretText" HorizontalAlignment="Center" TextWrapping="Wrap" Text="LOL" VerticalAlignment="Center" Width="60" Foreground="Black" TextAlignment="Center" FontSize="5.333"/>
</Grid>
</InkPresenter>
</Grid>
</Viewbox>
</Grid>
Stroke s;
int mycol = 0;
public MainPage()
{
InitializeComponent();
inkP.MouseMove += new MouseEventHandler(inkP_MouseMove);
for (int i = 0; i < 60; i++)
{
for (int l = 0; l < 60; l++)
{
Stroke bigStroke = new Stroke();
bigStroke.StylusPoints.Add(new StylusPoint(i, l));
inkP.Strokes.Add(bigStroke);
}
}
}
StylusPoint _lastPoint;
void inkP_MouseMove(object sender, MouseEventArgs e)
{
StylusPointCollection pointErasePoints = e.StylusDevice.GetStylusPoints(inkP);
pointErasePoints.Insert(0, new StylusPoint(e.GetPosition(inkP).X, e.GetPosition(inkP).Y));
//Compare collected stylus points with the ink presenter strokes and store the intersecting strokes.
StrokeCollection hitStrokes = inkP.Strokes.HitTest(pointErasePoints);
if (hitStrokes.Count > 0)
{
foreach (Stroke hitStroke in hitStrokes)
{
inkP.Strokes.Remove(hitStroke);
}
}
_lastPoint = pointErasePoints[pointErasePoints.Count - 1];
}
Your strokes are beeing removed point by point.
You can adjust this by changing your MainPage constructor to:
public MainPage()
{
InitializeComponent();
inkP.MouseMove += new MouseEventHandler(inkP_MouseMove);
for (int i = 0; i < 60; i++)
{
Stroke bigStroke = new Stroke();
for (int l = 0; l < 60; l++)
{
bigStroke.StylusPoints.Add(new StylusPoint(i, l));
}
inkP.Strokes.Add(bigStroke);
}
}
This will add the strokes line by line.
When you remove them, they will be removed line by line.
I am trying to create Rectangle programmaticallyin silverlight as fallows.
C#
private Boolean Working = false;
const int scale = 4;
const int size = 50;
Int32[] data = new Int32[size];
Rectangle[] lines = new Rectangle[size];
private void button1_Click(object sender, RoutedEventArgs e)
{
canvas1.Children.Clear();
for (int i = 0; i < data.Length; i++)
{
data[i] = i;
lines[i] = new Rectangle()
{
Height=i*scale,
Width = 10,
StrokeThickness=5,
Stroke = new SolidColorBrush(Colors.Red),
Name=i.ToString(),
};
canvas1.Children.Add(lines[i]);
}
}
Now the problem is that all the rectangle are created with the same height and width?.
XAML
<UserControl x:Class="SilverlightApplication1.MainPage"
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"
mc:Ignorable="d"
d:DesignHeight="500" d:DesignWidth="500">
<Canvas x:Name="canvas2" Background="White">
<Canvas x:Name="canvas1" Background="White"></Canvas>
<Button Content=" Generate" Height="38" Name="button1" Width="75" Click="button1_Click" Margin="0,352,245,24" HorizontalAlignment="Right" Canvas.Left="12" Canvas.Top="85" />
<Button Content="Shuffle" Height="38" HorizontalAlignment="Left" Name="button2" Margin="12,352,0,24" Click="button2_Click_1" Canvas.Left="81" Canvas.Top="85" Width="71" />
<Button Canvas.Left="181" Canvas.Top="437" Content="Bubble Sort" Height="38" Name="button3" Width="109" Click="button3_Click" />
</Canvas>
</UserControl>
Screenshot
Actually, everything works fine. All rectangles have different height. But you forget to move them, so they start overlapping. Change a little code and you'll see:
lines[i] = new Rectangle()
{
Height = i * scale,
Width = 10,
StrokeThickness = 5,
Stroke = new SolidColorBrush(Colors.Red),
Name = i.ToString(),
};
lines[i].Margin = new Thickness(11 * i, 0, 0, 0);
Result