How to override the parent layout/view opacity for certain elements in xamarin forms? - xaml

So I'm trying to develop a custom control which has Opacity of about 0.2, and its an entry, but the problem here is if I set the Opacity of the entry, then the Placeholder or the hint text also gets the opacity, and my custom control has an image as well, which gets the opacity as well, is there a way to override this?
I tried setting the alpha in the renderer but that doesn't seem to do the trick,
Here's my renderer and the output I need, but what I'm getting in actual
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (e.OldElement != null || e.NewElement == null)
return;
var element = (ImageEntry)this.Element;
this.Control.Placeholder = element.Placeholder;
var textField = this.Control;
if (!string.IsNullOrEmpty(element.Image))
{
switch (element.ImageAlignment)
{
case ImageAlignment.Left:
textField.LeftViewMode = UITextFieldViewMode.Always;
textField.LeftView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
break;
case ImageAlignment.Right:
textField.RightViewMode = UITextFieldViewMode.Always;
textField.RightView = GetImageView(element.Image, element.ImageHeight, element.ImageWidth);
break;
}
}
this.Control.Layer.CornerRadius = 25;
textField.BorderStyle = UITextBorderStyle.None;
textField.Alpha = 1;
CALayer bottomBorder = new CALayer
{
Frame = new CGRect(0.0f, element.HeightRequest - 1, this.Frame.Width, 1.0f),
BorderWidth = 2.0f,
BorderColor = element.LineColor.ToCGColor()
};
textField.Layer.AddSublayer(bottomBorder);
textField.Layer.MasksToBounds = true;
}
but this is what I'm getting

Related

wxwidget - issue of wxEVT_LEAVE_WINDOW event

I'd like to implement a card style UI(as the screen shot), card is using a wxPanel as a container, a static text and a static bmp in the panel. the card will zoom in and color changed when mouse on it, when the mouse leave the card, size and color will recover as normal state. I add some logic in onEnter and onLeave of wxPanel to handle zoom and color change. the card works fine in most of cases, but if mouse move quickly, multiple cards will be selected. From output log, it seems the issue happens in OnLeave, !GetClientRect().Contains(event.GetPosition()) = false, even the mouse actually has been out of the rect of the card. how can the card work as expected even mouse move quickly?
enter image description here
void TypeCard::OnEnter(wxMouseEvent& event) {
wxRect rect = GetClientRect();
wxPoint pnt = event.GetPosition();
TRACELOG_WARNING("###### On Enter left=%d top=%d width=%d height=%d", rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
TRACELOG_WARNING("&&&&&& On Enter x=%d y=%d", pnt.x, pnt.y);
if (GetClientRect().Contains(event.GetPosition()) && !selected_ ) {
TRACELOG_WARNING("&&&&&&On Enter = true");
if (m_bZoomEnabled) {
ZoomCard(zoom_in, 5, 5);
}
selected_ = true;
} else {
TRACELOG_WARNING("*****************************************************On Enter = false selected_ = %d", (int)selected_ );
}
// have_focus_ = true;
Refresh(false);
Update();
event.Skip();
}
void TypeCard::OnLeave(wxMouseEvent& event) {
wxRect rect = GetClientRect();
wxPoint pnt = event.GetPosition();
TRACELOG_WARNING("###### On OnLeave left=%d top=%d width=%d height=%d", rect.GetLeft(), rect.GetTop(), rect.GetWidth(), rect.GetHeight());
TRACELOG_WARNING("&&&&&& On OnLeave x=%d y=%d", pnt.x, pnt.y);
// if (!GetClientRect().Contains(event.GetPosition())) {
if (!rect.Contains(pnt)) {
if (m_bZoomEnabled) {
ZoomCard(zoom_out, 5, 5);
}
selected_ = false;
} else {
TRACELOG_WARNING("*****************************************************On OnLeave = false");
}
if (!selected_) {
// have_focus_ = false;
Refresh(false);
Update();
}
event.Skip();
}
void TypeCard::OnPaint(wxPaintEvent& event) {
wxPaintDC dc(this);
wxColour colour = selected_ ? CARD_SELECT_BACKGROUND_COLOUR : COMPONENT_UNSELECT_BACKGROUND_COLOUR;
wxCursor cur = selected_ ? wxCURSOR_HAND : wxCURSOR_ARROW;
dc.SetPen(wxPen(colour));
dc.SetBrush(wxBrush(colour));
this->SetCursor(cur);
const wxWindowList& list = this->GetChildren();
for (wxWindowList::compatibility_iterator node = list.GetFirst(); node; node = node->GetNext()) {
wxWindow* current = node->GetData();
if (current) {
current->SetBackgroundColour(colour);
current->SetCursor(cur);
}
}
dc.DrawRectangle(0, 0, this->GetSize().GetWidth(), GetSize().GetHeight());
}

How to show a badges count of ToolBarItem Icon in Xamarin Forms

It is not about how to show notification badges nor it's about to show toolbar item icon. It is clear question that how to show a badges count on a toolbar item icon. ?
I am sharing code to create ToolbarItem with icon in XF content page:
In cs File:
ToolbarItem cartItem = new ToolbarItem();
scanItem.Text = "My Cart";
scanItem.Order = ToolbarItemOrder.Primary;
scanItem.Icon = "carticon.png";
ToolbarItems.Add(cartItem );
In Xaml File:
<ContentPage.ToolbarItems>
<ToolbarItem Text="Cart" Priority="0" x:Name="menu1">
</ToolbarItem>
</ContentPage.ToolbarItems>
Now I want to Place a badge count on the above added tool bar item icon. How it can be achieved ?
Placing badge icon's in the native toolbars is actually more effort than its worth. If I need a badge icon, I remove the navigation page.
NavigationPage.SetHasNavigationBar(myPageInstance, false);
Then I create my own toolbar from scratch. In this toolbar, I can overlay an image in there, you can also place a number in it as needed. For example.
<Grid>
<Grid.GestureRecognizers>
<TapGestureRecognizer Command="{Binding IconCommand}" />
</Grid.GestureRecognizers>
<iconize:IconImage
Icon="fa-drawer"
IconColor="white"
IconSize="20" />
<Grid Margin="15,-15,0,0">
<iconize:IconImage Grid.Row="0"
HeightRequest="40"
WidthRequest="40"
Icon="fa-circle"
IconColor="red"
IsVisible="{Binding IsCircleVisible}"
IconSize="10" />
</Grid>
</Grid>
I use Iconize wtih FontAwesome for the icons
With the help of Xamarin Forum Discussion, I have achieved it. Read ad understand the complete discussion before implement it. Thank you "Slava Chernikoff", "Emanuele Sabetta", "Mirza Sikander", "Satish" to discuss and yours share code.
Setp 1: Create a Helper Class in PCL and install NGraphics package from nugget.
public class CartIconHelper
{
private static Graphic _svgGraphic = null;
public const string ResourcePath = "ToolBarAndroidBadge.Resources.cartIcon.svg";
private static PathOp[] RoundRect(NGraphics.Rect rect, double radius)
{
return new PathOp[]
{
new NGraphics.MoveTo(rect.X + radius, rect.Y),
new NGraphics.LineTo(rect.X + rect.Width - radius, rect.Y),
new NGraphics.ArcTo(new NGraphics.Size(radius, radius), true, false, new NGraphics.Point(rect.X + rect.Width, rect.Y + radius)),
new NGraphics.LineTo(rect.X + rect.Width, rect.Y + rect.Height - radius),
new NGraphics.ArcTo(new NGraphics.Size(radius, radius), true, false, new NGraphics.Point(rect.X + rect.Width - radius, rect.Y + rect.Height)),
new NGraphics.LineTo(rect.X + radius, rect.Y + rect.Height),
new NGraphics.ArcTo(new NGraphics.Size(radius, radius), true, false, new NGraphics.Point(rect.X, rect.Y + rect.Height - radius)),
new NGraphics.LineTo(rect.X, rect.Y + radius), new NGraphics.ArcTo(new NGraphics.Size(radius, radius), true, false, new NGraphics.Point(rect.X + radius, rect.Y)),
new NGraphics.ClosePath()
};
}
public static string DrawCartIcon(int count, string path, double iconSize = 30, double scale = 2, string fontName = "Arial", double fontSize = 12, double textSpacing = 4)
{
var service = DependencyService.Get<IService>();
var canvas = service.GetCanvas();
if (_svgGraphic == null) using (var stream = typeof(CartIconHelper).GetTypeInfo().Assembly.GetManifestResourceStream(path))
_svgGraphic = new SvgReader(new StreamReader(stream)).Graphic;
//st = ReadFully(stream);
var minSvgScale = Math.Min(canvas.Size.Width / _svgGraphic.Size.Width, canvas.Size.Height / _svgGraphic.Size.Height) / 1.15;
var w = _svgGraphic.Size.Width / minSvgScale;
var h = _svgGraphic.Size.Height / minSvgScale;
_svgGraphic.ViewBox = new NGraphics.Rect(0, -14, w, h);
_svgGraphic.Draw(canvas);
if (count > 0)
{
var text = count > 99 ? "99+" : count.ToString();
var font = new NGraphics.Font(fontName, fontSize);
var textSize = canvas.MeasureText(text, font);
var textRect = new NGraphics.Rect(canvas.Size.Width - textSize.Width - textSpacing, textSpacing, textSize.Width, textSize.Height);
if (count < 10)
{
var side = Math.Max(textSize.Width, textSize.Height);
var elipseRect = new NGraphics.Rect(canvas.Size.Width - side - 2 * textSpacing, 0, side + 2 * textSpacing, side + 2 * textSpacing);
canvas.FillEllipse(elipseRect, NGraphics.Colors.Red);
textRect -= new NGraphics.Point(side - textSize.Width, side - textSize.Height) / 2.0;
}
else
{
var elipseRect = new NGraphics.Rect(textRect.Left - textSpacing, textRect.Top - textSpacing, textRect.Width + 2 * textSpacing, textSize.Height + 2 * textSpacing);
canvas.FillPath(RoundRect(elipseRect, 6), NGraphics.Colors.Red);
}
var testReact1= new NGraphics.Rect(20,12,0,0);
// canvas.DrawText(text, textRect + new NGraphics.Point(0, textSize.Height), font, NGraphics.TextAlignment.Center, NGraphics.Colors.Black);
canvas.DrawText("5", testReact1, font, NGraphics.TextAlignment.Left, NGraphics.Colors.White);
}
service.SaveImage(canvas.GetImage());
string imagePath = service.GetImage();
return imagePath;
// return st;
}
}
Step 2: Create a interface to IService in PCL
public interface IService
{
IImageCanvas GetCanvas();
void SaveImage(NGraphics.IImage image);
string GetImage();
}
Step 3 : Implement this interface in your Android project
class CanvasServices:IService
{
private readonly AndroidPlatform _platform;
public CanvasServices()
{
_platform = new AndroidPlatform();
}
public void SaveImage(IImage image)
{
var dir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var filePath = System.IO.Path.Combine(dir, "cart.png");
var stream = new FileStream(filePath, FileMode.Create);
image.SaveAsPng(stream);
//bitmap.Compress(image., 100, stream);
stream.Close();
}
public string GetImage()
{
var dir = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
var filePath = System.IO.Path.Combine(dir, "cart.png");
using (var streamReader = new StreamReader(filePath))
{
string content = streamReader.ReadToEnd();
System.Diagnostics.Debug.WriteLine(content);
}
return filePath;
}
public IImageCanvas GetCanvas()
{
NGraphics.Size size = new NGraphics.Size(30);
return _platform.CreateImageCanvas(size);
}
public NGraphics.AndroidPlatform GetPlatform()
{
return _platform;
}
}
Setp 4: Now, use CartIcon Helper in your PCL project to show badges in TabBarItem.
public partial class MainPage : ContentPage
{
public MainPage()
{
InitializeComponent();
var imagePath = CartIconHelper.DrawCartIcon(2, "ToolBarAndroidBadge.Resources.cartIcon.svg");
string deviceSepecificFolderPath = Device.OnPlatform(null, imagePath, null);
object convertedObject = new FileImageSourceConverter().ConvertFromInvariantString(deviceSepecificFolderPath);
FileImageSource fileImageSource = (FileImageSource)convertedObject;
ToolbarItem cartItem = new ToolbarItem();
cartItem.Text = "My Cart";
cartItem.Order = ToolbarItemOrder.Primary;
cartItem.Icon = fileImageSource;
ToolbarItems.Add(cartItem);
}
}
For any one who wants to add badge on toolbar item using custom ui try,
Instead of using default toolbar item, you can hide the default navigation bar by NavigationPage.SetHasNavigationBar(this, false);
in the constructor.
Then prepare the custom navigation bar with toolbar item with badge as mentioned in above answers.
If you are using master detail page, hiding default navigation bar will hide hamburger icon, so need to slide from left to see sliding menu. Alternate method would be place a button with hamburger icon in custom navigation bar, on button click use messaging center to present the sliding menu.
Example: On page in which hamburger button is clicked
private void Button_Clicked(object sender, System.EventArgs e)
{
MessagingCenter.Send(this, "presnt");
}
On MasterDetail page
MessagingCenter.Subscribe<YourPage>(this, "presnt", (sender) =>
{
IsPresented = true;
});
Before making IsPresented=true, check for sliding menu is not all-ready presented.
Check https://github.com/LeslieCorrea/Xamarin-Forms-Shopping-Cart for badge on toolbar item.
Implement below code to draw a ground circle with text over toolbar icon
BarButtonItemExtensions.cs
using CoreAnimation;
using CoreGraphics;
using Foundation;
using ObjCRuntime;
using System;
using System.Linq;
using System.Runtime.InteropServices;
using UIKit;
namespace TeamCollaXform.Views.Services
{
public static class BarButtonItemExtensions
{
enum AssociationPolicy
{
ASSIGN = 0,
RETAIN_NONATOMIC = 1,
COPY_NONATOMIC = 3,
RETAIN = 01401,
COPY = 01403,
}
static NSString BadgeKey = new NSString(#"BadgeKey");
[DllImport(Constants.ObjectiveCLibrary)]
static extern void objc_setAssociatedObject(IntPtr obj, IntPtr key, IntPtr value, AssociationPolicy policy);
[DllImport(Constants.ObjectiveCLibrary)]
static extern IntPtr objc_getAssociatedObject(IntPtr obj, IntPtr key);
static CAShapeLayer GetBadgeLayer(UIBarButtonItem barButtonItem)
{
var handle = objc_getAssociatedObject(barButtonItem.Handle, BadgeKey.Handle);
if (handle != IntPtr.Zero)
{
var value = ObjCRuntime.Runtime.GetNSObject(handle);
if (value != null)
return value as CAShapeLayer;
else
return null;
}
return null;
}
static void DrawRoundedRect(CAShapeLayer layer, CGRect rect, float radius, UIColor color, bool filled)
{
layer.FillColor = filled ? color.CGColor : UIColor.White.CGColor;
layer.StrokeColor = color.CGColor;
layer.Path = UIBezierPath.FromRoundedRect(rect, radius).CGPath;
}
public static void AddBadge(this UIBarButtonItem barButtonItem, string text, UIColor backgroundColor, UIColor textColor, bool filled = true, float fontSize = 11.0f)
{
if (string.IsNullOrEmpty(text))
{
return;
}
CGPoint offset = CGPoint.Empty;
if (backgroundColor == null)
backgroundColor = UIColor.Red;
var font = UIFont.SystemFontOfSize(fontSize);
if (UIDevice.CurrentDevice.CheckSystemVersion(9, 0))
{
font = UIFont.MonospacedDigitSystemFontOfSize(fontSize, UIFontWeight.Regular);
}
var view = barButtonItem.ValueForKey(new NSString(#"view")) as UIView;
var bLayer = GetBadgeLayer(barButtonItem);
bLayer?.RemoveFromSuperLayer();
var badgeSize = text.StringSize(font);
var height = badgeSize.Height;
var width = badgeSize.Width + 5; /* padding */
//make sure we have at least a circle
if (width < height)
{
width = height;
}
//x position is offset from right-hand side
var x = view.Frame.Width - width + offset.X;
var badgeFrame = new CGRect(new CGPoint(x: x - 4, y: offset.Y + 5), size: new CGSize(width: width, height: height));
bLayer = new CAShapeLayer();
DrawRoundedRect(bLayer, badgeFrame, 7.0f, backgroundColor, filled);
view.Layer.AddSublayer(bLayer);
// Initialiaze Badge's label
var label = new CATextLayer();
label.String = text;
label.TextAlignmentMode = CATextLayerAlignmentMode.Center;
label.SetFont(CGFont.CreateWithFontName(font.Name));
label.FontSize = font.PointSize;
label.Frame = badgeFrame;
label.ForegroundColor = filled ? textColor.CGColor : UIColor.White.CGColor;
label.BackgroundColor = UIColor.Clear.CGColor;
label.ContentsScale = UIScreen.MainScreen.Scale;
bLayer.AddSublayer(label);
// Save Badge as UIBarButtonItem property
objc_setAssociatedObject(barButtonItem.Handle, BadgeKey.Handle, bLayer.Handle, AssociationPolicy.RETAIN_NONATOMIC);
}
public static void UpdateBadge(this UIBarButtonItem barButtonItem, string text, UIColor backgroundColor, UIColor textColor)
{
var bLayer = GetBadgeLayer(barButtonItem);
if (string.IsNullOrEmpty(text) || text == "0")
{
bLayer?.RemoveFromSuperLayer();
objc_setAssociatedObject(barButtonItem.Handle, BadgeKey.Handle, new CAShapeLayer().Handle, AssociationPolicy.ASSIGN);
return;
}
var textLayer = bLayer?.Sublayers?.First(p => p is CATextLayer) as CATextLayer;
if (textLayer != null)
{
textLayer.String = text;
}
else
{
barButtonItem.AddBadge(text, backgroundColor, textColor);
}
}
}
}
ToolbarItemBadgeService.cs
using TeamCollaXform.Views.Services;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;
[assembly: Dependency(typeof(ToolbarItemBadgeService))]
namespace TeamCollaXform.Views.Services
{
/// <summary>
///
/// </summary>
public interface IToolbarItemBadgeService
{
void SetBadge(Page page, ToolbarItem item, string value, Color backgroundColor, Color textColor);
}
/// <summary>
///
/// </summary>
public class ToolbarItemBadgeService : IToolbarItemBadgeService
{
public void SetBadge(Page page, ToolbarItem item, string value, Color backgroundColor, Color textColor)
{
Device.BeginInvokeOnMainThread(() =>
{
var renderer = Platform.GetRenderer(page);
if (renderer == null)
{
renderer = Platform.CreateRenderer(page);
Platform.SetRenderer(page, renderer);
}
var vc = renderer.ViewController;
var rightButtomItems = vc?.ParentViewController?.NavigationItem?.RightBarButtonItems;
var idx = rightButtomItems.Length - page.ToolbarItems.IndexOf(item) - 1; //Revert
if (rightButtomItems != null && rightButtomItems.Length > idx)
{
var barItem = rightButtomItems[idx];
if (barItem != null)
{
barItem.UpdateBadge(value, backgroundColor.ToUIColor(), textColor.ToUIColor());
}
}
});
}
}
}
Usage
void OnAttachClicked(object sender, EventArgs e)
{
//var answer = await DisplayAlert("Question?", "Would you like to play a game", "Yes", "No");
//Debug.WriteLine("Answer: " + answer);
ToolbarItem cmdItem = sender as ToolbarItem;
DependencyService.Get<IToolbarItemBadgeService>().SetBadge(this, cmdItem, $"2", Color.DarkOrange, Color.White);
}
Links: 1) for instruction and 2) for sample code
https://www.xamboy.com/2018/03/08/adding-badge-to-toolbaritem-in-xamarin-forms/
https://github.com/CrossGeeks/ToolbarItemBadgeSample

Change highlight color of NSTableView selected row

how to change NSTable selected row background color?
here is good answer, but it is for uitable view .
For now,what I see is that I can change selected hilight style :
MyTAble.SelectionHighlightStyle = NSTableViewSelectionHighlightStyle.Regular;
But here is only 3 options;
None = -1L,
Regular,
SourceList
I have tried following solution :
patientListDelegate.SelectionChanged += (o, e) => {
var r = PatientTableView.SelectedRow;
var v = PatientTableView.GetRowView (r, false);
v.Emphasized = false;
};
It works normally , but if I minimize and then open application again , still shows blue color
I found answer in objective-c
Change selection color on view-based NSTableView
Here is c# implementation:
inside delegate :
public override NSTableRowView CoreGetRowView (NSTableView tableView, nint row)
{
var rowView = tableView.MakeView ("row", this);
if (rowView == null) {
rowView = new PatientTableRow ();
rowView.Identifier = "row";
}
return rowView as NSTableRowView;
}
and custom row :
public class PatientTableRow : NSTableRowView
{
public override void DrawSelection (CGRect dirtyRect)
{
if (SelectionHighlightStyle != NSTableViewSelectionHighlightStyle.None) {
NSColor.FromCalibratedWhite (0.65f, 1.0f).SetStroke ();
NSColor.FromCalibratedWhite (0.82f, 1.0f).SetFill ();
var selectionPath = NSBezierPath.FromRoundedRect (dirtyRect, 0, 0);
selectionPath.Fill ();
selectionPath.Stroke ();
}
}
}

Color change a background in processing w/ out affecting particles

I'm trying to fade a background in and out into different colors. I decided to try drawing a rect rather than using background, but I'm getting trails on my particles, because the background isn't getting drawn. Suggestions on how to fix this?
// main tab
ArrayList<ParticleSystem> systems;
PVector windRight = new PVector(0.1,0);
PVector sortaSpeed = new PVector(-0.1,0);
PVector gravity = new PVector(0,0.05);
boolean wR = false;
boolean sP = false;
boolean cS = false;
int limit = 8;
int alpha = 10;
color[] colorArray = {color(0,0,0,alpha),color(16, 37, 43,alpha),color(51, 10, 10,alpha),color(126, 255, 0,alpha)};
int currentColor;
int nextColor;
boolean change = false;
void setup() {
size(640,480);
systems = new ArrayList<ParticleSystem>();
smooth();
noStroke();
currentColor = 0;
for(int i = 0; i < limit; i++){
systems.add(new ParticleSystem(random(100,200),10,new PVector(random(100,500),-5))); //random(480)
}
background(0);
}
void draw() {
//rect(0, 0, 2000, 2000);
fill(colorArray[currentColor]);
rect(0, 0, width*2, height*2);
//background(colorArray[currentColor]);
if(change){
currentColor = nextColor;
change = false;
}
if(!systems.isEmpty()){
for (int i =0; i < systems.size(); i++){
ParticleSystem ps = systems.get(i);
ps.applyForce(gravity);
ps.run();
if(wR){
ps.applyForce(windRight);
}
if(sP){
ps.applyForce(sortaSpeed);
}
}
}
}
void keyPressed() {
if(key == 'w'){
wR = true;
print("w");
}
if(key == 'a'){
print('a');
sP = true;
}
}
void keyReleased(){
if(key == 'w'){
wR = false;
} else if(key == 'a'){
sP = false;
} else if(key == 's'){
if(key == 's'){
change = true;
println("currentColor: "+currentColor);
int newColor = currentColor;
while (newColor == currentColor)
newColor=(int) random(colorArray.length);
nextColor = newColor;
}
} // end of cS
}
In the future, please try to post an MCVE. Right now we can't run your code because it contains compiler errors. We don't need to see your entire sketch anyway though, just a small example that gets the point across.
But your problem is caused because you're trying to use alpha values in your background. That won't work with the background() function because that function ignores alpha values, and it won't work with the rect() function because then you won't be clearing out old frames- you'll see them through the transparent rectangle.
Instead, you could use the lerpColor() function to calculate the transition from one color to another over time.
Here's an example that transitions between random colors:
color fromColor = getRandomColor();
color toColor = getRandomColor();
float currentLerpValue = 0;
float lerpStep = .01;
void draw() {
color currentColor = lerpColor(fromColor, toColor, currentLerpValue);
currentLerpValue += lerpStep;
if (currentLerpValue >= 1) {
fromColor = currentColor;
toColor= getRandomColor();
currentLerpValue = 0;
}
background(currentColor);
}
color getRandomColor() {
return color(random(255), random(255), random(255));
}

WP7: LayoutTransform a ListBoxItem

Here's my XAML:
<ListBox x:Name="MyListBox" FontSize="40"
SelectionChanged="MyListBox_SelectionChanged">
</ListBox>
In this code-behind (below), I am attempting to animate a delete action. When the item is selected I delete it. I visually animate it with a ScaleTransform. In WPF I would use a LayoutTransform, but since I only have RenderTransform in WP/SL, I am using RenderTransform - and as a result the surrounding layout is not responding to the change in size. The record is still correctly deleted, but the visual effect is diminished.
Is there a way to do this in WP? Is there a way to resize a ListBoxItem so that the surrounding content responds?
ObservableCollection<string> m_Data;
public MainPage()
{
InitializeComponent();
m_Data = new ObservableCollection<string>
{ "One", "Two", "Three", "Four" };
MyListBox.ItemsSource = m_Data;
}
private void MyListBox_SelectionChanged(object sender,
SelectionChangedEventArgs e)
{
// fetch ListBoxItem
if (e.AddedItems.Count == 0)
return;
var _Data = e.AddedItems[0] as string;
var _Item = MyListBox.ItemContainerGenerator
.ContainerFromItem(_Data) as ListBoxItem;
// setup to resize using scale transform
var _Scale = new ScaleTransform
{
CenterX = _Item.RenderSize.Width / 2,
CenterY = _Item.RenderSize.Height / 2,
ScaleX = .99,
ScaleY = .99
};
_Item.RenderTransform = _Scale;
// setup storyboard
var _Story = new Storyboard();
_Story.Completed += (s, e1) =>
{
// remove data from collection
m_Data.Remove(_Data);
};
// animate scale X
var _AnimationX = new DoubleAnimation
{
To = .01,
Duration = TimeSpan.FromSeconds(2),
};
_Story.Children.Add(_AnimationX);
Storyboard.SetTarget(_AnimationX, _Scale);
Storyboard.SetTargetProperty(_AnimationX,
new PropertyPath(ScaleTransform.ScaleXProperty));
// animate scale Y
var _AnimationY = new DoubleAnimation
{
To = .01,
Duration = TimeSpan.FromSeconds(2),
};
_Story.Children.Add(_AnimationY);
Storyboard.SetTarget(_AnimationY, _Scale);
Storyboard.SetTargetProperty(_AnimationY,
new PropertyPath(ScaleTransform.ScaleYProperty));
_Story.Begin();
}
You can also use LayoutTransform on Windows Phone so I would just use that. .