I've looked all over the place, but it seems that examples I have seen allow only numbers 0-9
I'm writing a Pythagorean Theorem program. I wish to have the phone (Windows Phone 7) check if there are ANY alpha (A-Z, a-z), symbols (#,%), or anything other than a number in the textbox. If not, then it will continue computing. I want to check so there will be no future errors.
This is basically a bad pseudocode of what I want it to do
txtOne-->any alpha?--No-->any symbols--No-->continue...
I would actually prefer a command to check if the string is completely a number.
Thanks in advance!
An even better way to ensure that your textbox is a number is to handle the KeyPress event. You can then choose what characters you want to allow. In the following example we disallow all characters that are not digits:
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
// If the character is not a digit, don't let it show up in the textbox.
if (!char.IsDigit(e.KeyChar))
e.Handled = true;
}
This ensures that your textbox text is a number because it only allows digits to be entered.
This is something I just came up with to allow decimal values (and apparently the backspace key):
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (char.IsDigit(e.KeyChar))
{
return;
}
if (e.KeyChar == (char)Keys.Back)
{
return;
}
if (e.KeyChar == '.' && !textBox1.Text.Contains('.'))
{
return;
}
e.Handled = true;
}
There are several ways to do this:
You can use TryParse() and check if the return value is not false.
You can use Regex to validate:
Match match = Regex.Match(textBox.Text, #"^\d+$");
if (match.Success) { ... }
// or
if (Regex.IsMatch(textBox.Text, #"^\d+$")) { ... }
Or you can simply only give them the Numeric keyboard. There are several different keyboard layouts you can use. Link
If you want to do more indepth, I have used the KeyDown and KeyUp events to check what was entered and handle the keypress. Link
You can define the textbox's input scope.
Example:
<TextBox InputScope="Digits"></TextBox>
You can use TryParse and see if there is a result.
See http://msdn.microsoft.com/en-us/library/system.int64.tryparse.aspx
Int64 output;
if (!Int64.TryParse(input, out output)
{
ShowErrorMessage();
return
}
Continue..
/// <summary>
/// A numeric-only textbox.
/// </summary>
public class NumericOnlyTextBox : TextBox
{
#region Properties
#region AllowDecimals
/// <summary>
/// Gets or sets a value indicating whether [allow decimals].
/// </summary>
/// <value>
/// <c>true</c> if [allow decimals]; otherwise, <c>false</c>.
/// </value>
public bool AllowDecimals
{
get { return (bool)GetValue(AllowDecimalsProperty); }
set { SetValue(AllowDecimalsProperty, value); }
}
/// <summary>
/// The allow decimals property
/// </summary>
public static readonly DependencyProperty AllowDecimalsProperty =
DependencyProperty.Register("AllowDecimals", typeof(bool),
typeof(NumericOnlyTextBox), new UIPropertyMetadata(false));
#endregion
#region MaxValue
/// <summary>
/// Gets or sets the max value.
/// </summary>
/// <value>
/// The max value.
/// </value>
public double? MaxValue
{
get { return (double?)GetValue(MaxValueProperty); }
set { SetValue(MaxValueProperty, value); }
}
/// <summary>
/// The max value property
/// </summary>
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(double?),
typeof(NumericOnlyTextBox), new UIPropertyMetadata(null));
#endregion
#region MinValue
/// <summary>
/// Gets or sets the min value.
/// </summary>
/// <value>
/// The min value.
/// </value>
public double? MinValue
{
get { return (double?)GetValue(MinValueProperty); }
set { SetValue(MinValueProperty, value); }
}
/// <summary>
/// The min value property
/// </summary>
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue", typeof(double?),
typeof(NumericOnlyTextBox), new UIPropertyMetadata(null));
#endregion
#endregion
#region Contructors
/// <summary>
/// Initializes a new instance of the <see cref="NumericOnlyTextBox" /> class.
/// </summary>
public NumericOnlyTextBox()
{
this.PreviewTextInput += OnPreviewTextInput;
}
#endregion
#region Methods
/// <summary>
/// Numeric-Only text field.
/// </summary>
/// <param name="text">The text.</param>
/// <returns></returns>
public bool NumericOnlyCheck(string text)
{
// regex that matches disallowed text
var regex = (AllowDecimals) ? new Regex("[^0-9.]+") : new Regex("[^0-9]+");
return !regex.IsMatch(text);
}
#endregion
#region Events
/// <summary>
/// Called when [preview text input].
/// </summary>
/// <param name="sender">The sender.</param>
/// <param name="e">The <see cref="TextCompositionEventArgs" /> instance
/// containing the event data.</param>
/// <exception cref="System.NotImplementedException"></exception>
private void OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
// Check number
if (this.NumericOnlyCheck(e.Text))
{
// Evaluate min value
if (MinValue != null && Convert.ToDouble(this.Text + e.Text) < MinValue)
{
this.Text = MinValue.ToString();
this.SelectionStart = this.Text.Length;
e.Handled = true;
}
// Evaluate max value
if (MaxValue != null && Convert.ToDouble(this.Text + e.Text) > MaxValue)
{
this.Text = MaxValue.ToString();
this.SelectionStart = this.Text.Length;
e.Handled = true;
}
}
else
{
e.Handled = true;
}
}
#endregion
}
Related
I have a custom Checkbox is implemented as below;
public class CheckBox : View, INotifyPropertyChanged
{
/// <summary>
/// The checked state property.
/// </summary>
public static readonly BindableProperty CheckedProperty =
BindableProperty.Create<CheckBox, bool>(
p => p.Checked, false, BindingMode.TwoWay, propertyChanged: OnCheckedPropertyChanged);
/// <summary>
/// The checked text property.
/// </summary>
public static readonly BindableProperty CheckedTextProperty =
BindableProperty.Create<CheckBox, string>(
p => p.CheckedText, string.Empty, BindingMode.TwoWay);
/// <summary>
/// The unchecked text property.
/// </summary>
public static readonly BindableProperty UncheckedTextProperty =
BindableProperty.Create<CheckBox, string>(
p => p.UncheckedText, string.Empty);
/// <summary>
/// The default text property.
/// </summary>
public static readonly BindableProperty DefaultTextProperty =
BindableProperty.Create<CheckBox, string>(
p => p.Text, string.Empty,BindingMode.TwoWay, propertyChanged: OnDefaultTextChanged);
/// <summary>
/// Identifies the TextColor bindable property.
/// </summary>
///
/// <remarks/>
public static readonly BindableProperty TextColorProperty =
BindableProperty.Create<CheckBox, Color>(
p => p.TextColor, Color.Default);
/// <summary>
/// The font size property
/// </summary>
public static readonly BindableProperty FontSizeProperty =
BindableProperty.Create<CheckBox, double>(
p => p.FontSize, -1);
/// <summary>
/// The font name property.
/// </summary>
public static readonly BindableProperty FontNameProperty =
BindableProperty.Create<CheckBox, string>(
p => p.FontName, string.Empty);
/// <summary>
/// The checked changed event.
/// </summary>
public event EventHandler<EventArgs<bool>> CheckedChanged;
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Gets or sets a value indicating whether the control is checked.
/// </summary>
/// <value>The checked state.</value>
public bool Checked
{
get
{
return this.GetValue<bool>(CheckedProperty);
}
set
{
if (this.Checked != value)
{
this.SetValue(CheckedProperty, value);
this.CheckedChanged.Invoke(this, value);
}
}
}
/// <summary>
/// Gets or sets a value indicating the checked text.
/// </summary>
/// <value>The checked state.</value>
/// <remarks>
/// Overwrites the default text property if set when checkbox is checked.
/// </remarks>
public string CheckedText
{
get
{
return this.GetValue<string>(CheckedTextProperty);
}
set
{
this.SetValue(CheckedTextProperty, value);
}
}
/// <summary>
/// Gets or sets a value indicating whether the control is checked.
/// </summary>
/// <value>The checked state.</value>
/// <remarks>
/// Overwrites the default text property if set when checkbox is checked.
/// </remarks>
public string UncheckedText
{
get
{
return this.GetValue<string>(UncheckedTextProperty);
}
set
{
this.SetValue(UncheckedTextProperty, value);
}
}
/// <summary>
/// Gets or sets the text.
/// </summary>
public string DefaultText
{
get
{
return this.GetValue<string>(DefaultTextProperty);
}
set
{
this.SetValue(DefaultTextProperty, value);
NotifyPropertyChanged("DefaultTextProperty");
NotifyPropertyChanged("DefaultText");
}
}
/// <summary>
/// Gets or sets the color of the text.
/// </summary>
/// <value>The color of the text.</value>
public Color TextColor
{
get
{
return this.GetValue<Color>(TextColorProperty);
}
set
{
this.SetValue(TextColorProperty, value);
}
}
/// <summary>
/// Gets or sets the size of the font.
/// </summary>
/// <value>The size of the font.</value>
public double FontSize
{
get
{
return (double)GetValue(FontSizeProperty);
}
set
{
SetValue(FontSizeProperty, value);
}
}
/// <summary>
/// Gets or sets the name of the font.
/// </summary>
/// <value>The name of the font.</value>
public string FontName
{
get
{
return (string)GetValue(FontNameProperty);
}
set
{
SetValue(FontNameProperty, value);
}
}
/// <summary>
/// Gets the text.
/// </summary>
/// <value>The text.</value>
public string Text
{
get
{
return this.Checked
? (string.IsNullOrEmpty(this.CheckedText) ? this.DefaultText : this.CheckedText)
: (string.IsNullOrEmpty(this.UncheckedText) ? this.DefaultText : this.UncheckedText);
}
}
/// <summary>
/// Called when [checked property changed].
/// </summary>
/// <param name="bindable">The bindable.</param>
/// <param name="oldvalue">if set to <c>true</c> [oldvalue].</param>
/// <param name="newvalue">if set to <c>true</c> [newvalue].</param>
private static void OnCheckedPropertyChanged(BindableObject bindable, bool oldvalue, bool newvalue)
{
var checkBox = (CheckBox)bindable;
checkBox.Checked = newvalue;
}
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
I have default text bindable property, that I want to set the value from coming web service via Binding.
The code I tried on Xaml is as below;
<uikit:CheckBox x:Name="CheckBox" WidthRequest="250" HeightRequest="100" FontSize="13" DefaultText="{Binding FirstText,Mode=TwoWay}" CheckedChanged="CheckBox_Clicked" TextColor="#263238" />
I am not able to do so... I tried setting Binding Context in both Xaml and Codebehind.
What am I doing wrong?
Could you please help me?
I have also added PropertyChanged Event Handler, my updated code is as above. It still does not update.
BR,
add this at end
public void RaiseCheckedChanged (bool val)
{
if (CheckedChanged != null)
CheckedChanged (this, new EventArgs<bool> (val));
}
and add this class in same file
public class EventArgs<T> : EventArgs
{
/// <summary>
/// Initializes a new instance of the <see cref="EventArgs"/> class.
/// </summary>
/// <param name="value">Value of the argument</param>
public EventArgs(T value)
{
this.Value = value;
}
/// <summary>
/// Gets the value of the event argument
/// </summary>
public T Value { get; private set; }
}
public static class BindableObjectExtensions
{
/// <summary>
/// Gets the value.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="bindableObject">The bindable object.</param>
/// <param name="property">The property.</param>
/// <returns>T.</returns>
public static T GetValue<T>(this BindableObject bindableObject, BindableProperty property)
{
return (T)bindableObject.GetValue(property);
}
}
public static class EventExtensions
{
/// <summary>
/// Raise the specified event.
/// </summary>
/// <param name="handler">Event handler.</param>
/// <param name="sender">Sender object.</param>
/// <param name="value">Argument value.</param>
/// <typeparam name="T">The value type.</typeparam>
public static void Invoke<T>(this EventHandler<EventArgs<T>> handler, object sender, T value)
{
var handle = handler;
if (handle != null)
{
handle(sender, new EventArgs<T>(value));
}
}
/// <summary>
/// Tries the invoke.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="handler">The handler.</param>
/// <param name="sender">The sender.</param>
/// <param name="args">The arguments.</param>
/// <returns><c>true</c> if XXXX, <c>false</c> otherwise.</returns>
public static bool TryInvoke<T>(this EventHandler<T> handler, object sender, T args) where T : EventArgs
{
var handle = handler;
if (handle == null) return false;
handle(sender, args);
return true;
}
}
Well, first try was with a readily made spinning wheel (a gif). After that, I found a code that dynamically generates a wheel, but no way in both cases to have full transparency.
Depending on what I set as parent (form or panel) and the position on my wheel on form, the spin is just half transparent.
I use C# express (VS 2008).
All I want is a nice wheel in center of form, activated when BG is doing something, but full transparent so I can resize form.
Thanks,
Update:
I worked on some code that is draw a spinning wheel just fine. Almost working except OnPantBackground() which needs to be empty to paint behind, but in this case, a black rectangle is drawn because of ControlStyles.OptimizedDoubleBuffer enabled.
Any suggestions? Thank you.
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using System.Drawing.Drawing2D;
namespace WinFormsControls
{
/// <summary>
/// A label that can be transparent.
/// </summary>
public class TransparentLabel : Control
{
// Constants =========================================================
private const double NumberOfDegreesInCircle = 360;
private const double NumberOfDegreesInHalfCircle = NumberOfDegreesInCircle / 2;
private const int DefaultInnerCircleRadius = 8;
private const int DefaultOuterCircleRadius = 10;
private const int DefaultNumberOfSpoke = 10;
private const int DefaultSpokeThickness = 4;
private readonly Color DefaultColor = Color.DarkGray;
private const int MacOSXInnerCircleRadius = 5;
private const int MacOSXOuterCircleRadius = 11;
private const int MacOSXNumberOfSpoke = 12;
private const int MacOSXSpokeThickness = 2;
private const int FireFoxInnerCircleRadius = 6;
private const int FireFoxOuterCircleRadius = 7;
private const int FireFoxNumberOfSpoke = 9;
private const int FireFoxSpokeThickness = 4;
private const int IE7InnerCircleRadius = 8;
private const int IE7OuterCircleRadius = 9;
private const int IE7NumberOfSpoke = 24;
private const int IE7SpokeThickness = 4;
// Enumeration =======================================================
public enum StylePresets
{
MacOSX,
Firefox,
IE7,
Custom
}
// Attributes ========================================================
private Timer m_Timer;
private bool m_IsTimerActive;
private int m_NumberOfSpoke;
private int m_SpokeThickness;
private int m_ProgressValue;
private int m_OuterCircleRadius;
private int m_InnerCircleRadius;
private PointF m_CenterPoint;
private Color m_Color;
private Color[] m_Colors;
private double[] m_Angles;
private StylePresets m_StylePreset;
// Properties ========================================================
/// <summary>
/// Gets or sets the lightest color of the circle.
/// </summary>
/// <value>The lightest color of the circle.</value>
[TypeConverter("System.Drawing.ColorConverter"),
Category("LoadingCircle"),
Description("Sets the color of spoke.")]
public Color Color
{
get
{
return m_Color;
}
set
{
m_Color = value;
GenerateColorsPallet();
Invalidate();
}
}
/// <summary>
/// Gets or sets the outer circle radius.
/// </summary>
/// <value>The outer circle radius.</value>
[System.ComponentModel.Description("Gets or sets the radius of outer circle."),
System.ComponentModel.Category("LoadingCircle")]
public int OuterCircleRadius
{
get
{
if (m_OuterCircleRadius == 0)
m_OuterCircleRadius = DefaultOuterCircleRadius;
return m_OuterCircleRadius;
}
set
{
m_OuterCircleRadius = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the inner circle radius.
/// </summary>
/// <value>The inner circle radius.</value>
[System.ComponentModel.Description("Gets or sets the radius of inner circle."),
System.ComponentModel.Category("LoadingCircle")]
public int InnerCircleRadius
{
get
{
if (m_InnerCircleRadius == 0)
m_InnerCircleRadius = DefaultInnerCircleRadius;
return m_InnerCircleRadius;
}
set
{
m_InnerCircleRadius = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the number of spoke.
/// </summary>
/// <value>The number of spoke.</value>
[System.ComponentModel.Description("Gets or sets the number of spoke."),
System.ComponentModel.Category("LoadingCircle")]
public int NumberSpoke
{
get
{
if (m_NumberOfSpoke == 0)
m_NumberOfSpoke = DefaultNumberOfSpoke;
return m_NumberOfSpoke;
}
set
{
if (m_NumberOfSpoke != value && m_NumberOfSpoke > 0)
{
m_NumberOfSpoke = value;
GenerateColorsPallet();
GetSpokesAngles();
Invalidate();
}
}
}
/// <summary>
/// Gets or sets a value indicating whether this <see cref="T:LoadingCircle"/> is active.
/// </summary>
/// <value><c>true</c> if active; otherwise, <c>false</c>.</value>
[System.ComponentModel.Description("Gets or sets the number of spoke."),
System.ComponentModel.Category("LoadingCircle")]
public bool Active
{
get
{
return m_IsTimerActive;
}
set
{
m_IsTimerActive = value;
ActiveTimer();
}
}
/// <summary>
/// Gets or sets the spoke thickness.
/// </summary>
/// <value>The spoke thickness.</value>
[System.ComponentModel.Description("Gets or sets the thickness of a spoke."),
System.ComponentModel.Category("LoadingCircle")]
public int SpokeThickness
{
get
{
if (m_SpokeThickness <= 0)
m_SpokeThickness = DefaultSpokeThickness;
return m_SpokeThickness;
}
set
{
m_SpokeThickness = value;
Invalidate();
}
}
/// <summary>
/// Gets or sets the rotation speed.
/// </summary>
/// <value>The rotation speed.</value>
[System.ComponentModel.Description("Gets or sets the rotation speed. Higher the slower."),
System.ComponentModel.Category("LoadingCircle")]
public int RotationSpeed
{
get
{
return m_Timer.Interval;
}
set
{
if (value > 0)
m_Timer.Interval = value;
}
}
/// <summary>
/// Quickly sets the style to one of these presets, or a custom style if desired
/// </summary>
/// <value>The style preset.</value>
[Category("LoadingCircle"),
Description("Quickly sets the style to one of these presets, or a custom style if desired"),
DefaultValue(typeof(StylePresets), "Custom")]
public StylePresets StylePreset
{
get { return m_StylePreset; }
set
{
m_StylePreset = value;
switch (m_StylePreset)
{
case StylePresets.MacOSX:
SetCircleAppearance(MacOSXNumberOfSpoke,
MacOSXSpokeThickness, MacOSXInnerCircleRadius,
MacOSXOuterCircleRadius);
break;
case StylePresets.Firefox:
SetCircleAppearance(FireFoxNumberOfSpoke,
FireFoxSpokeThickness, FireFoxInnerCircleRadius,
FireFoxOuterCircleRadius);
break;
case StylePresets.IE7:
SetCircleAppearance(IE7NumberOfSpoke,
IE7SpokeThickness, IE7InnerCircleRadius,
IE7OuterCircleRadius);
break;
case StylePresets.Custom:
SetCircleAppearance(DefaultNumberOfSpoke,
DefaultSpokeThickness,
DefaultInnerCircleRadius,
DefaultOuterCircleRadius);
break;
}
}
}
/// <summary>
/// Creates a new <see cref="TransparentLabel"/> instance.
/// </summary>
public TransparentLabel()
{
TabStop = false;
InitializeComponent();
SetStyle(ControlStyles.UserPaint, true);
//SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.ResizeRedraw, true);
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
m_Color = DefaultColor;
GenerateColorsPallet();
GetSpokesAngles();
GetControlCenterPoint();
m_Timer = new Timer();
m_Timer.Tick += new EventHandler(aTimer_Tick);
ActiveTimer();
this.Resize += new EventHandler(LoadingCircle_Resize);
this.DoubleBuffered = true;
this.SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.ContainerControl |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.SupportsTransparentBackColor
, true);
}
// Events ============================================================
/// <summary>
/// Handles the Resize event of the LoadingCircle control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
void LoadingCircle_Resize(object sender, EventArgs e)
{
GetControlCenterPoint();
}
/// <summary>
/// Handles the Tick event of the aTimer control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="T:System.EventArgs"/> instance containing the event data.</param>
void aTimer_Tick(object sender, EventArgs e)
{
m_ProgressValue = ++m_ProgressValue % m_NumberOfSpoke;
Invalidate();
}
/// <summary>
/// Gets the creation parameters.
/// </summary>
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x20;
return cp;
}
}
// Overridden Methods ================================================
/// <summary>
/// Retrieves the size of a rectangular area into which a control can be fitted.
/// </summary>
/// <param name="proposedSize">The custom-sized area for a control.</param>
/// <returns>
/// An ordered pair of type <see cref="T:System.Drawing.Size"></see> representing the width and height of a rectangle.
/// </returns>
public override Size GetPreferredSize(Size proposedSize)
{
proposedSize.Width =
(m_OuterCircleRadius + m_SpokeThickness) * 2;
return proposedSize;
}
/// <summary>
/// Paints the background.
/// </summary>
/// <param name="e">E.</param>
///
protected override void OnPaintBackground(PaintEventArgs e)
{
// do nothing
}
/// <summary>
/// Paints the control.
/// </summary>
/// <param name="e">E.</param>
protected override void OnPaint(PaintEventArgs e)
{
//DrawText();
if (m_NumberOfSpoke > 0)
{
e.Graphics.SmoothingMode = SmoothingMode.HighQuality;
int intPosition = m_ProgressValue;
for (int intCounter = 0; intCounter < m_NumberOfSpoke; intCounter++)
{
intPosition = intPosition % m_NumberOfSpoke;
DrawLine(e.Graphics,
GetCoordinate(m_CenterPoint, m_InnerCircleRadius, m_Angles[intPosition]),
GetCoordinate(m_CenterPoint, m_OuterCircleRadius, m_Angles[intPosition]),
m_Colors[intCounter], m_SpokeThickness);
intPosition++;
}
}
base.OnPaint(e);
}
/*
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
if (m.Msg == 0x000F)
{
DrawText();
}
}
private void DrawText()
{
using (Graphics graphics = CreateGraphics())
using (SolidBrush brush = new SolidBrush(ForeColor))
{
SizeF size = graphics.MeasureString(Text, Font);
// first figure out the top
float top = 0;
switch (textAlign)
{
case ContentAlignment.MiddleLeft:
case ContentAlignment.MiddleCenter:
case ContentAlignment.MiddleRight:
top = (Height - size.Height) / 2;
break;
case ContentAlignment.BottomLeft:
case ContentAlignment.BottomCenter:
case ContentAlignment.BottomRight:
top = Height - size.Height;
break;
}
float left = -1;
switch (textAlign)
{
case ContentAlignment.TopLeft:
case ContentAlignment.MiddleLeft:
case ContentAlignment.BottomLeft:
if (RightToLeft == RightToLeft.Yes)
left = Width - size.Width;
else
left = -1;
break;
case ContentAlignment.TopCenter:
case ContentAlignment.MiddleCenter:
case ContentAlignment.BottomCenter:
left = (Width - size.Width) / 2;
break;
case ContentAlignment.TopRight:
case ContentAlignment.MiddleRight:
case ContentAlignment.BottomRight:
if (RightToLeft == RightToLeft.Yes)
left = -1;
else
left = Width - size.Width;
break;
}
graphics.DrawString(Text, Font, brush, left, top);
}
}
*/
/*
/// <summary>
/// Gets or sets the text associated with this control.
/// </summary>
/// <returns>
/// The text associated with this control.
/// </returns>
public override string Text
{
get
{
return base.Text;
}
set
{
base.Text = value;
RecreateHandle();
}
}
/// <summary>
/// Gets or sets a value indicating whether control's elements are aligned to support locales using right-to-left fonts.
/// </summary>
/// <value></value>
/// <returns>
/// One of the <see cref="T:System.Windows.Forms.RightToLeft"/> values. The default is <see cref="F:System.Windows.Forms.RightToLeft.Inherit"/>.
/// </returns>
/// <exception cref="T:System.ComponentModel.InvalidEnumArgumentException">
/// The assigned value is not one of the <see cref="T:System.Windows.Forms.RightToLeft"/> values.
/// </exception>
public override RightToLeft RightToLeft
{
get
{
return base.RightToLeft;
}
set
{
base.RightToLeft = value;
RecreateHandle();
}
}
/// <summary>
/// Gets or sets the font of the text displayed by the control.
/// </summary>
/// <value></value>
/// <returns>
/// The <see cref="T:System.Drawing.Font"/> to apply to the text displayed by the control. The default is the value of the <see cref="P:System.Windows.Forms.Control.DefaultFont"/> property.
/// </returns>
public override Font Font
{
get
{
return base.Font;
}
set
{
base.Font = value;
RecreateHandle();
}
}
private ContentAlignment textAlign = ContentAlignment.TopLeft;
/// <summary>
/// Gets or sets the text alignment.
/// </summary>
public ContentAlignment TextAlign
{
get { return textAlign; }
set
{
textAlign = value;
RecreateHandle();
}
}
*/
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
// Methods ===========================================================
/// <summary>
/// Darkens a specified color.
/// </summary>
/// <param name="_objColor">Color to darken.</param>
/// <param name="_intPercent">The percent of darken.</param>
/// <returns>The new color generated.</returns>
private Color Darken(Color _objColor, int _intPercent)
{
int intRed = _objColor.R;
int intGreen = _objColor.G;
int intBlue = _objColor.B;
return Color.FromArgb(_intPercent, Math.Min(intRed, byte.MaxValue), Math.Min(intGreen, byte.MaxValue), Math.Min(intBlue, byte.MaxValue));
}
/// <summary>
/// Generates the colors pallet.
/// </summary>
private void GenerateColorsPallet()
{
m_Colors = GenerateColorsPallet(m_Color, Active, m_NumberOfSpoke);
}
/// <summary>
/// Generates the colors pallet.
/// </summary>
/// <param name="_objColor">Color of the lightest spoke.</param>
/// <param name="_blnShadeColor">if set to <c>true</c> the color will be shaded on X spoke.</param>
/// <returns>An array of color used to draw the circle.</returns>
private Color[] GenerateColorsPallet(Color _objColor, bool _blnShadeColor, int _intNbSpoke)
{
Color[] objColors = new Color[NumberSpoke];
// Value is used to simulate a gradient feel... For each spoke, the
// color will be darken by value in intIncrement.
byte bytIncrement = (byte)(byte.MaxValue / NumberSpoke);
//Reset variable in case of multiple passes
byte PERCENTAGE_OF_DARKEN = 0;
for (int intCursor = 0; intCursor < NumberSpoke; intCursor++)
{
if (_blnShadeColor)
{
if (intCursor == 0 || intCursor < NumberSpoke - _intNbSpoke)
objColors[intCursor] = _objColor;
else
{
// Increment alpha channel color
PERCENTAGE_OF_DARKEN += bytIncrement;
// Ensure that we don't exceed the maximum alpha
// channel value (255)
if (PERCENTAGE_OF_DARKEN > byte.MaxValue)
PERCENTAGE_OF_DARKEN = byte.MaxValue;
// Determine the spoke forecolor
objColors[intCursor] = Darken(_objColor, PERCENTAGE_OF_DARKEN);
}
}
else
objColors[intCursor] = _objColor;
}
return objColors;
}
/// <summary>
/// Gets the control center point.
/// </summary>
private void GetControlCenterPoint()
{
m_CenterPoint = GetControlCenterPoint(this);
}
/// <summary>
/// Gets the control center point.
/// </summary>
/// <returns>PointF object</returns>
private PointF GetControlCenterPoint(Control _objControl)
{
return new PointF(_objControl.Width / 2, _objControl.Height / 2 - 1);
}
/// <summary>
/// Draws the line with GDI+.
/// </summary>
/// <param name="_objGraphics">The Graphics object.</param>
/// <param name="_objPointOne">The point one.</param>
/// <param name="_objPointTwo">The point two.</param>
/// <param name="_objColor">Color of the spoke.</param>
/// <param name="_intLineThickness">The thickness of spoke.</param>
private void DrawLine(Graphics _objGraphics, PointF _objPointOne, PointF _objPointTwo,
Color _objColor, int _intLineThickness)
{
using (Pen objPen = new Pen(new SolidBrush(_objColor), _intLineThickness))
{
objPen.StartCap = LineCap.Round;
objPen.EndCap = LineCap.Round;
_objGraphics.DrawLine(objPen, _objPointOne, _objPointTwo);
}
}
/// <summary>
/// Gets the coordinate.
/// </summary>
/// <param name="_objCircleCenter">The Circle center.</param>
/// <param name="_intRadius">The radius.</param>
/// <param name="_dblAngle">The angle.</param>
/// <returns></returns>
private PointF GetCoordinate(PointF _objCircleCenter, int _intRadius, double _dblAngle)
{
double dblAngle = Math.PI * _dblAngle / NumberOfDegreesInHalfCircle;
return new PointF(_objCircleCenter.X + _intRadius * (float)Math.Cos(dblAngle),
_objCircleCenter.Y + _intRadius * (float)Math.Sin(dblAngle));
}
/// <summary>
/// Gets the spokes angles.
/// </summary>
private void GetSpokesAngles()
{
m_Angles = GetSpokesAngles(NumberSpoke);
}
/// <summary>
/// Gets the spoke angles.
/// </summary>
/// <param name="_shtNumberSpoke">The number spoke.</param>
/// <returns>An array of angle.</returns>
private double[] GetSpokesAngles(int _intNumberSpoke)
{
double[] Angles = new double[_intNumberSpoke];
double dblAngle = (double)NumberOfDegreesInCircle / _intNumberSpoke;
for (int shtCounter = 0; shtCounter < _intNumberSpoke; shtCounter++)
Angles[shtCounter] = (shtCounter == 0 ? dblAngle : Angles[shtCounter - 1] + dblAngle);
return Angles;
}
/// <summary>
/// Actives the timer.
/// </summary>
private void ActiveTimer()
{
if (m_IsTimerActive)
{
m_Timer.Start();
}
else
{
m_Timer.Stop();
m_ProgressValue = 0;
}
GenerateColorsPallet();
Invalidate();
}
/// <summary>
/// Sets the circle appearance.
/// </summary>
/// <param name="numberSpoke">The number spoke.</param>
/// <param name="spokeThickness">The spoke thickness.</param>
/// <param name="innerCircleRadius">The inner circle radius.</param>
/// <param name="outerCircleRadius">The outer circle radius.</param>
public void SetCircleAppearance(int numberSpoke, int spokeThickness,
int innerCircleRadius, int outerCircleRadius)
{
NumberSpoke = numberSpoke;
SpokeThickness = spokeThickness;
InnerCircleRadius = innerCircleRadius;
OuterCircleRadius = outerCircleRadius;
Invalidate();
}
}
}
Sorry for answering my own post, but after testing a lot of projects, modify without success, I finally found one that is almost full transparent
https://www.codeproject.com/Articles/27185/WYSIWYG-Progress-Circle-for-NET-Framework-C
That guy made a very well job almost 10 years ago, at least inner part of spin is copied and re-drawn in OnPaint so quite nice transparent over RichTextBox control where all other projects failed :)
The only small problem is that the circle trail, don't copy the bmp behind so there will always be a comet effect, but I can live with that! Much pleasant effect than other solutions, including few on stackoverflow.
In case anyone will need!
Wow that seems incredibly complicated. I don't know much about wpf, but on iOS what we usually do is load an image that has the exact properties we need (here, transparent background), and just rotate the image to make the spinning effect.
You only need very little logic to make it appear/disappear and rotate. For a very basic spinner you get to create and use that class in a matter of seconds.
At least that's the route I'd go for, instead of writing 300 lines of code to manually handle the spinner :p
Basic Requirement - Displaying In App tiles in Universal Apps.
I have gone through samples of Hub Tiles from the following link Hub Tiles which applies to Windows Phone 7 and 8, 8.1 (Silverlight), but there is no mentioning of windows Phone 8.1 (Universal Applications). Even if i include the assembly separately it throws an error that Microsoft.Phone cannot be resolved.
As a work around I have even downloaded the source of hub Tiles from Windows phone Toolkit Source and resolved the assemblies, modified the templates and edited it accordingly. But I might be missing on some points, Although It is showing as a control in the tool box but it is not even visible when I add it to XAML. I am adding the edited code for all the three files available from the source of the toolkit.
HubTiles.cs
// (c) Copyright Microsoft Corporation.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.
using System.Windows;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Data;
using Windows.UI.Xaml.Media;
namespace Microsoft.Phone.Controls
{
/// <summary>
/// Represents an animated tile that supports an image and a title.
/// Furthermore, it can also be associated with a message or a notification.
/// </summary>
/// <QualityBand>Preview</QualityBand>
[TemplateVisualState(Name = Expanded, GroupName = ImageStates)]
[TemplateVisualState(Name = Semiexpanded, GroupName = ImageStates)]
[TemplateVisualState(Name = Collapsed, GroupName = ImageStates)]
[TemplateVisualState(Name = Flipped, GroupName = ImageStates)]
[TemplatePart(Name = NotificationBlock, Type = typeof(TextBlock))]
[TemplatePart(Name = MessageBlock, Type = typeof(TextBlock))]
[TemplatePart(Name = BackTitleBlock, Type = typeof(TextBlock))]
[TemplatePart(Name = TitlePanel, Type = typeof(Panel))]
public class HubTile : Control
{
/// <summary>
/// Common visual states.
/// </summary>
private const string ImageStates = "ImageState";
/// <summary>
/// Expanded visual state.
/// </summary>
private const string Expanded = "Expanded";
/// <summary>
/// Semiexpanded visual state.
/// </summary>
private const string Semiexpanded = "Semiexpanded";
/// <summary>
/// Collapsed visual state.
/// </summary>
private const string Collapsed = "Collapsed";
/// <summary>
/// Flipped visual state.
/// </summary>
private const string Flipped = "Flipped";
/// <summary>
/// Nofitication Block template part name.
/// </summary>
private const string NotificationBlock = "NotificationBlock";
/// <summary>
/// Message Block template part name.
/// </summary>
private const string MessageBlock = "MessageBlock";
/// <summary>
/// Back Title Block template part name.
/// </summary>
private const string BackTitleBlock = "BackTitleBlock";
/// <summary>
/// Title Panel template part name.
/// </summary>
private const string TitlePanel = "TitlePanel";
/// <summary>
/// Notification Block template part.
/// </summary>
private TextBlock _notificationBlock;
/// <summary>
/// Message Block template part.
/// </summary>
private TextBlock _messageBlock;
/// <summary>
/// Title Panel template part.
/// </summary>
private Panel _titlePanel;
/// <summary>
/// Back Title Block template part.
/// </summary>
private TextBlock _backTitleBlock;
/// <summary>
/// Represents the number of steps inside the pipeline of stalled images
/// </summary>
internal int _stallingCounter;
/// <summary>
/// Flag that determines if the hub tile has a primary text string associated to it.
/// If it does not, the hub tile will not drop.
/// </summary>
internal bool _canDrop;
/// <summary>
/// Flag that determines if the hub tile has a secondary text string associated to it.
/// If it does not, the hub tile will not flip.
/// </summary>
internal bool _canFlip;
#region Source DependencyProperty
/// <summary>
/// Gets or sets the image source.
/// </summary>
public ImageSource Source
{
get { return (ImageSource)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
/// <summary>
/// Identifies the Source dependency property.
/// </summary>
public static readonly DependencyProperty SourceProperty =
DependencyProperty.Register("Source", typeof(ImageSource), typeof(HubTile), new PropertyMetadata(null));
#endregion
#region Title DependencyProperty
/// <summary>
/// Gets or sets the title.
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
/// <summary>
/// Identifies the Title dependency property.
/// </summary>
public static readonly DependencyProperty TitleProperty =
DependencyProperty.Register("Title", typeof(string), typeof(HubTile), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnTitleChanged)));
/// <summary>
/// Prevents the hub tile from transitioning into a Semiexpanded or Collapsed visual state if the title is not set.
/// </summary>
/// <param name="obj">The dependency object.</param>
/// <param name="e">The event information.</param>
private static void OnTitleChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
HubTile tile = (HubTile)obj;
if (string.IsNullOrEmpty((string)e.NewValue))
{
tile._canDrop = false;
tile.State = ImageState.Expanded;
}
else
{
tile._canDrop = true;
}
}
#endregion
#region Notification DependencyProperty
/// <summary>
/// Gets or sets the notification alert.
/// </summary>
public string Notification
{
get { return (string)GetValue(NotificationProperty); }
set { SetValue(NotificationProperty, value); }
}
/// <summary>
/// Identifies the Notification dependency property.
/// </summary>
public static readonly DependencyProperty NotificationProperty =
DependencyProperty.Register("Notification", typeof(string), typeof(HubTile), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnBackContentChanged)));
/// <summary>
/// Prevents the hub tile from transitioning into a Flipped visual state if neither the notification alert nor the message are set.
/// </summary>
/// <param name="obj">The dependency object.</param>
/// <param name="e">The event information.</param>
private static void OnBackContentChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
HubTile tile = (HubTile)obj;
// If there is a new notification or a message, the hub tile can flip.
if ((!(string.IsNullOrEmpty(tile.Notification)) && tile.DisplayNotification)
|| (!(string.IsNullOrEmpty(tile.Message)) && !tile.DisplayNotification))
{
tile._canFlip = true;
}
else
{
tile._canFlip = false;
tile.State = ImageState.Expanded;
}
}
#endregion
#region Message DependencyProperty
/// <summary>
/// Gets or sets the message.
/// </summary>
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty, value); }
}
/// <summary>
/// Identifies the Message dependency property.
/// </summary>
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message", typeof(string), typeof(HubTile), new PropertyMetadata(string.Empty, new PropertyChangedCallback(OnBackContentChanged)));
#endregion
#region DisplayNotification DependencyProperty
/// <summary>
/// Gets or sets the flag for new notifications.
/// </summary>
public bool DisplayNotification
{
get { return (bool)GetValue(DisplayNotificationProperty); }
set { SetValue(DisplayNotificationProperty, value); }
}
/// <summary>
/// Identifies the DisplayNotification dependency property.
/// </summary>
public static readonly DependencyProperty DisplayNotificationProperty =
DependencyProperty.Register("DisplayNotification", typeof(bool), typeof(HubTile), new PropertyMetadata(false, new PropertyChangedCallback(OnBackContentChanged)));
#endregion
#region IsFrozen DependencyProperty
/// <summary>
/// Gets or sets the flag for images that do not animate.
/// </summary>
public bool IsFrozen
{
get { return (bool)GetValue(IsFrozenProperty); }
set { SetValue(IsFrozenProperty, value); }
}
/// <summary>
/// Identifies the IsFrozen dependency property.
/// </summary>
public static readonly DependencyProperty IsFrozenProperty =
DependencyProperty.Register("IsFrozen", typeof(bool), typeof(HubTile), new PropertyMetadata(false, new PropertyChangedCallback(OnIsFrozenChanged)));
/// <summary>
/// Removes the frozen image from the enabled image pool or the stalled image pipeline.
/// Adds the non-frozen image to the enabled image pool.
/// </summary>
/// <param name="obj">The dependency object.</param>
/// <param name="e">The event information.</param>
private static void OnIsFrozenChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
HubTile tile = (HubTile)obj;
if ((bool)e.NewValue)
{
HubTileService.FreezeHubTile(tile);
}
else
{
HubTileService.UnfreezeHubTile(tile);
}
}
#endregion
#region GroupTag DependencyProperty
/// <summary>
/// Gets or sets the group tag.
/// </summary>
public string GroupTag
{
get { return (string)GetValue(GroupTagProperty); }
set { SetValue(GroupTagProperty, value); }
}
/// <summary>
/// Identifies the GroupTag dependency property.
/// </summary>
public static readonly DependencyProperty GroupTagProperty =
DependencyProperty.Register("GroupTag", typeof(string), typeof(HubTile), new PropertyMetadata(string.Empty));
#endregion
#region State DependencyProperty
/// <summary>
/// Gets or sets the visual state.
/// </summary>
internal ImageState State
{
get { return (ImageState)GetValue(StateProperty); }
set { SetValue(StateProperty, value); }
}
/// <summary>
/// Identifies the State dependency property.
/// </summary>
private static readonly DependencyProperty StateProperty =
DependencyProperty.Register("State", typeof(ImageState), typeof(HubTile), new PropertyMetadata(ImageState.Expanded, OnImageStateChanged));
/// <summary>
/// Triggers the transition between visual states.
/// </summary>
/// <param name="obj">The dependency object.</param>
/// <param name="e">The event information.</param>
private static void OnImageStateChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
((HubTile)obj).UpdateVisualState();
}
#endregion
#region Size DependencyProperty
/// <summary>
/// Gets or sets the visual state.
/// </summary>
public TileSize Size
{
get { return (TileSize)GetValue(SizeProperty); }
set { SetValue(SizeProperty, value); }
}
/// <summary>
/// Identifies the State dependency property.
/// </summary>
public static readonly DependencyProperty SizeProperty =
DependencyProperty.Register("Size", typeof(TileSize), typeof(HubTile), new PropertyMetadata(TileSize.Default, OnSizeChanged));
/// <summary>
/// Triggers the transition between visual states.
/// </summary>
/// <param name="obj">The dependency object.</param>
/// <param name="e">The event information.</param>
private static void OnSizeChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
HubTile hubTile = (HubTile)obj;
// And now we'll update the width and height to match the new size.
switch (hubTile.Size)
{
case TileSize.Default:
hubTile.Width = 173;
hubTile.Height = 173;
break;
case TileSize.Small:
hubTile.Width = 99;
hubTile.Height = 99;
break;
case TileSize.Medium:
hubTile.Width = 210;
hubTile.Height = 210;
break;
case TileSize.Large:
hubTile.Width = 432;
hubTile.Height = 210;
break;
}
hubTile.SizeChanged += OnHubTileSizeChanged;
HubTileService.FinalizeReference(hubTile);
}
static void OnHubTileSizeChanged(object sender, SizeChangedEventArgs e)
{
HubTile hubTile = (HubTile)sender;
hubTile.SizeChanged -= OnHubTileSizeChanged;
// In order to avoid getting into a bad state, we'll shift the HubTile
// back to the Expanded state. If we were already in the Expanded state,
// then we'll manually shift the title panel to the right location,
// since the visual state manager won't do it for us in that case.
if (hubTile.State != ImageState.Expanded)
{
hubTile.State = ImageState.Expanded;
VisualStateManager.GoToState(hubTile, Expanded, false);
}
else if (hubTile._titlePanel != null)
{
CompositeTransform titlePanelTransform = hubTile._titlePanel.RenderTransform as CompositeTransform;
if (titlePanelTransform != null)
{
titlePanelTransform.TranslateY = -hubTile.Height;
}
}
HubTileService.InitializeReference(hubTile);
}
#endregion
/// <summary>
/// Updates the visual state.
/// </summary>
private void UpdateVisualState()
{
string state;
// If we're in the Small size, then we should just display the image
// instead of having animations.
if (Size != TileSize.Small)
{
switch (State)
{
case ImageState.Expanded:
state = Expanded;
break;
case ImageState.Semiexpanded:
state = Semiexpanded;
break;
case ImageState.Collapsed:
state = Collapsed;
break;
case ImageState.Flipped:
state = Flipped;
break;
default:
state = Expanded;
break;
}
}
else
{
state = Expanded;
}
VisualStateManager.GoToState(this, state, true);
}
/// <summary>
/// Gets the template parts and sets binding.
/// </summary>
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
_notificationBlock = base.GetTemplateChild(NotificationBlock) as TextBlock;
_messageBlock = base.GetTemplateChild(MessageBlock) as TextBlock;
_backTitleBlock = base.GetTemplateChild(BackTitleBlock) as TextBlock;
_titlePanel = base.GetTemplateChild(TitlePanel) as Panel;
//Do binding in code to avoid exposing unnecessary value converters.
if (_notificationBlock != null)
{
Binding bindVisible = new Binding();
bindVisible.Source = this;
bindVisible.Path = new PropertyPath("DisplayNotification");
bindVisible.Converter = new VisibilityConverter();
bindVisible.ConverterParameter = false;
_notificationBlock.SetBinding(TextBlock.VisibilityProperty, bindVisible);
}
if(_messageBlock != null)
{
Binding bindCollapsed = new Binding();
bindCollapsed.Source = this;
bindCollapsed.Path = new PropertyPath("DisplayNotification");
bindCollapsed.Converter = new VisibilityConverter();
bindCollapsed.ConverterParameter = true;
_messageBlock.SetBinding(TextBlock.VisibilityProperty, bindCollapsed);
}
if(_backTitleBlock != null)
{
Binding bindTitle = new Binding();
bindTitle.Source = this;
bindTitle.Path = new PropertyPath("Title");
bindTitle.Converter = new MultipleToSingleLineStringConverter();
_backTitleBlock.SetBinding(TextBlock.TextProperty, bindTitle);
}
UpdateVisualState();
}
/// <summary>
/// Initializes a new instance of the HubTile class.
/// </summary>
public HubTile()
{
DefaultStyleKey = typeof(HubTile);
Loaded += HubTile_Loaded;
Unloaded += HubTile_Unloaded;
}
/// <summary>
/// This event handler gets called as soon as a hub tile is added to the visual tree.
/// A reference of this hub tile is passed on to the service singleton.
/// </summary>
/// <param name="sender">The hub tile.</param>
/// <param name="e">The event information.</param>
void HubTile_Loaded(object sender, RoutedEventArgs e)
{
HubTileService.InitializeReference(this);
}
/// <summary>
/// This event handler gets called as soon as a hub tile is removed from the visual tree.
/// Any existing reference of this hub tile is eliminated from the service singleton.
/// </summary>
/// <param name="sender">The hub tile.</param>
/// <param name="e">The event information.</param>
void HubTile_Unloaded(object sender, RoutedEventArgs e)
{
HubTileService.FinalizeReference(this);
}
}
/// <summary>
/// Represents the visual states of a Hub tile.
/// </summary>
internal enum ImageState
{
/// <summary>
/// Expanded visual state value.
/// </summary>
Expanded = 0,
/// <summary>
/// Semiexpanded visual state value.
/// </summary>
Semiexpanded = 1,
/// <summary>
/// Collapsed visual state value.
/// </summary>
Collapsed = 2,
/// <summary>
/// Flipped visual state value.
/// </summary>
Flipped = 3,
};
/// <summary>
/// Represents the size of a Hub tile.
/// </summary>
public enum TileSize
{
/// <summary>
/// Default size (173 px x 173 px).
/// </summary>
Default,
/// <summary>
/// Small size (99 px x 99 px).
/// </summary>
Small,
/// <summary>
/// Medium size (210 px x 210 px).
/// </summary>
Medium,
/// <summary>
/// Large size (432 px x 210 px).
/// </summary>
Large,
};
}
Note: We can edit the same for HubTileConverters and HubTileService but still it doesnt work.
If any one has a solution or has edited the same for Universal Application Or if there is any Toolkit from Microsoft for the same then please let me know.
TIA.
I have ported the toolkit HubTile stuff. Done with a sample for your refrence please find in the following link.
HubTile sample for universal app
Hope this will help you.
Maybe you should check the Generic.xaml file in toolkit source code, it is placed in Themes folder. All toolkit control default styles are stored in this file. It seems your problem is lack of this style file.
Because HubTile is a custom control, it will read the \Themes\Generic.xaml in solution by using DefaultStyleKey = typeof(HubTile) in its constructor. You should port this file to your solution.
I’m using Silverlight 5.
I’m having problem to enter decimal point in my TextBox. Every time I entered a decimal point, the cursor will always return back to the beginning of value entered in the TextBox and the decimal point will be removed.
Strange thing is that this problem only occurs when I deploy my application on IIS and running it from internet browser. The problem was NOT there when I run it from Visual Studio 2010 in debug mode.
Bellow is my XAML code for the TextBox:
<TextBox Grid.Column="2" Grid.Row="1" Text="{Binding Path=SelectedModel.MyHight,
Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Helper:TextBoxFilter.Filter="PositiveDecimal"/>
The Helper Class TextBoxFilter actually doing the PositiveDecimal filtering. Bellow are the classes (These are not my codes. Got it somewhere in the internet):
TextBoxFilterType.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace NumericUpdateSourceProblem
{
public enum TextBoxFilterType
{
None,
PositiveInteger,
Integer,
PositiveDecimal,
Decimal,
Alpha,
}
}
TextBoxFilter.cs
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
namespace NumericUpdateSourceProblem
{
public class TextBoxFilter
{
/// <summary>
/// Filter Attached Dependency Property
/// </summary>
public static readonly DependencyProperty FilterProperty =
DependencyProperty.RegisterAttached("Filter", typeof(TextBoxFilterType), typeof(TextBoxFilter),
new PropertyMetadata(OnFilterChanged));
/// <summary>
/// Gets the Filter property.
/// </summary>
public static TextBoxFilterType GetFilter(DependencyObject d)
{
return (TextBoxFilterType)d.GetValue(FilterProperty);
}
/// <summary>
/// Sets the Filter property.
/// </summary>
public static void SetFilter(DependencyObject d, TextBoxFilterType value)
{
d.SetValue(FilterProperty, value);
}
/// <summary>
/// Handles changes to the Filter property.
/// </summary>
/// <param name="d">DependencyObject</param>
/// <param name="e">The <see cref="System.Windows.DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void OnFilterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
TextBox textBox = d as TextBox;
if (TextBoxFilterType.None != (TextBoxFilterType)e.OldValue)
{
textBox.KeyDown -= new KeyEventHandler(textBox_KeyDown);
}
if (TextBoxFilterType.None != (TextBoxFilterType)e.NewValue)
{
textBox.KeyDown += new KeyEventHandler(textBox_KeyDown);
}
}
/// <summary>
/// Handles the KeyDown event of the textBox control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.Windows.Input.KeyEventArgs"/> instance containing the event data.</param>
private static void textBox_KeyDown(object sender, KeyEventArgs e)
{
// bypass other keys!
if (IsValidOtherKey(e.Key))
{
return;
}
//
TextBoxFilterType filterType = GetFilter((DependencyObject)sender);
TextBox textBox = sender as TextBox;
if (null == textBox)
{
textBox = e.OriginalSource as TextBox;
}
//
switch (filterType)
{
case TextBoxFilterType.PositiveInteger:
e.Handled = !IsValidIntegerKey(textBox, e.Key, e.PlatformKeyCode, false);
break;
case TextBoxFilterType.Integer:
e.Handled = !IsValidIntegerKey(textBox, e.Key, e.PlatformKeyCode, true);
break;
ase TextBoxFilterType.PositiveDecimal:
e.Handled = !IsValidDecmialKey(textBox, e.Key, e.PlatformKeyCode, false);
break;
case TextBoxFilterType.Decimal:
e.Handled = !IsValidDecmialKey(textBox, e.Key, e.PlatformKeyCode, true);
break;
case TextBoxFilterType.Alpha:
e.Handled = !IsValidAlphaKey(e.Key);
break;
}
}
/// <summary>
/// Determines whether the specified key is valid other key.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>
/// <c>true</c> if [is valid other key] [the specified key]; otherwise, <c>false</c>.
/// </returns>
private static bool IsValidOtherKey(Key key)
{
// allow control keys
if ((Keyboard.Modifiers & ModifierKeys.Control) != 0)
{
return true;
}
// allow
// Back, Tab, Enter, Shift, Ctrl, Alt, CapsLock, Escape, PageUp, PageDown
// End, Home, Left, Up, Right, Down, Insert, Delete
// except for space!
// allow all Fx keys
if (
(key < Key.D0 && key != Key.Space)
|| (key > Key.Z && key < Key.NumPad0))
{
return true;
}
// we need to examine all others!
return false;
}
/// <summary>
/// Determines whether the specified key is valid integer key for the specified text box.
/// </summary>
/// <param name="textBox">The text box.</param>
/// <param name="key">The key.</param>
/// <param name="platformKeyCode">The platform key code.</param>
/// <param name="negativeAllowed">if set to <c>true</c> [negative allowed].</param>
/// <returns>
/// <c>true</c> if the specified key is valid integer key for the specified text box; otherwise, <c>false</c>.
/// </returns>
private static bool IsValidIntegerKey(TextBox textBox, Key key, int platformKeyCode, bool negativeAllowed)
{
if ((Keyboard.Modifiers & ModifierKeys.Shift) != 0)
{
return false;
}
if (Key.D0 <= key && key <= Key.D9)
{
return true;
}
if (Key.NumPad0 <= key && key <= Key.NumPad9)
{
return true;
}
if (negativeAllowed && (key == Key.Subtract || (key == Key.Unknown && platformKeyCode == 189)))
{
return 0 == textBox.Text.Length;
}
//
return false;
}
/// <summary>
/// Determines whether the specified key is valid decmial key for the specified text box.
/// </summary>
/// <param name="textBox">The text box.</param>
/// <param name="key">The key.</param>
/// <param name="platformKeyCode">The platform key code.</param>
/// <param name="negativeAllowed">if set to <c>true</c> [negative allowed].</param>
/// <returns>
/// <c>true</c> if the specified key is valid decmial key for the specified text box; otherwise, <c>false</c>.
/// </returns>
private static bool IsValidDecmialKey(TextBox textBox, Key key, int platformKeyCode, bool negativeAllowed)
{
if (IsValidIntegerKey(textBox, key, platformKeyCode, negativeAllowed))
{
return true;
}
if (key == Key.Decimal || (key == Key.Unknown && platformKeyCode == 190))
{
return !textBox.Text.Contains(".");
}
return false;
//
}
/// <summary>
/// Determines whether the specified key is valid alpha key.
/// </summary>
/// <param name="key">The key.</param>
/// <returns>
/// <c>true</c> if the specified key is valid alpha key for the specified text box; otherwise, <c>false</c>.
/// </returns>
private static bool IsValidAlphaKey(Key key)
{
if (Key.A <= key && key <= Key.Z)
{
return true;
}
//
return false;
//
}
}
}
I don’t understand why it behave differently in development environment (debug) and implementation environment (deploy on IIS version 5.1).
p.s: If I remove UpdateSourceTrigger=PropertyChanged in Text properties, it will works fine. But I need that property to update source without losing focus.
Download Source Code here
Thank You
Please change MyHeight property to string instead of double in MyModel class. I have faced similar issue before and solved it this way. Yes you have to do the unnecessary boxing and unboxing between string and double here.But this works.
My combobox returns a set of values from s stored procedure as this
private void BindCombo()
{
DataCombo.FillCombo(ComboDS(2313001), cmbClass, 0);
DataCombo.FillCombo(DDCombo(5007), cmbGroup, 0);
}
I managed to give a rudimentary auto complete suggestion as IsTextSearchenabled but cannot get a auto suggestion box that i would like.
I have seen loads of examples of autocomplete/suggestive textboxes but none of them seem to suit me.
this code apparently suits me.
but how would i use the auto suggest here
using System;
using System.ComponentModel;
using System.Globalization;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
namespace DotNetZen.AutoFilteredComboBox
{
public class AutoFilteredComboBox : ComboBox
{
private int silenceEvents = 0;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
DependencyPropertyDescriptor textProperty = DependencyPropertyDescriptor.FromProperty(
ComboBox.TextProperty, typeof(AutoFilteredComboBox));
textProperty.AddValueChanged(this, this.OnTextChanged);
this.RegisterIsCaseSensitiveChangeNotification();
}
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[System.ComponentModel.Description("The way the combo box treats the case sensitivity of typed text.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
protected virtual void OnIsCaseSensitiveChanged(object sender, EventArgs e)
{
if (this.IsCaseSensitive)
this.IsTextSearchEnabled = false;
this.RefreshFilter();
}
private void RegisterIsCaseSensitiveChangeNotification()
{
System.ComponentModel.DependencyPropertyDescriptor.FromProperty(IsCaseSensitiveProperty, typeof(AutoFilteredComboBox)).AddValueChanged(
this, this.OnIsCaseSensitiveChanged);
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(true));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[System.ComponentModel.Description("The way the combo box behaves when it receives focus.")]
[System.ComponentModel.Category("AutoFiltered ComboBox")]
[System.ComponentModel.DefaultValue(true)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle selection |
/// <summary>
/// Called when <see cref="ComboBox.ApplyTemplate()"/> is called.
/// </summary>
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
this.EditableTextBox.SelectionChanged += this.EditableTextBox_SelectionChanged;
}
/// <summary>
/// Gets the text box in charge of the editable portion of the combo box.
/// </summary>
protected TextBox EditableTextBox
{
get
{
return ((TextBox)base.GetTemplateChild("PART_EditableTextBox"));
}
}
private int start = 0, length = 0;
private void EditableTextBox_SelectionChanged(object sender, RoutedEventArgs e)
{
if (this.silenceEvents == 0)
{
this.start = ((TextBox)(e.OriginalSource)).SelectionStart;
this.length = ((TextBox)(e.OriginalSource)).SelectionLength;
this.RefreshFilter();
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (this.Text.Length == 0)
return true;
string prefix = this.Text;
// If the end of the text is selected, do not mind it.
if (this.length > 0 && this.start + this.length == this.Text.Length)
{
prefix = prefix.Substring(0, this.start);
}
return value.ToString()
.StartsWith(prefix, !this.IsCaseSensitive, CultureInfo.CurrentCulture);
}
#endregion
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(System.Collections.IEnumerable oldValue, System.Collections.IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, EventArgs e)
{
if (!this.IsTextSearchEnabled && this.silenceEvents == 0)
{
this.RefreshFilter();
// Manually simulate the automatic selection that would have been
// available if the IsTextSearchEnabled dependency property was set.
if (this.Text.Length > 0)
{
foreach (object item in CollectionViewSource.GetDefaultView(this.ItemsSource))
{
int text = item.ToString().Length, prefix = this.Text.Length;
this.SelectedItem = item;
this.silenceEvents++;
this.EditableTextBox.Text = item.ToString();
this.EditableTextBox.Select(prefix, text - prefix);
this.silenceEvents--;
break;
}
}
}
}
}
}
Also found the AutoFilteredComboBox to be very simple to work with. Though I have made some changes:
Removed use of DependencyPropertyDescriptor to avoid memory leak of combobox-objects
Introduced FilterItem-event and FilterList-event to allow one to customize the filtering
Changed default filtering from starts-with-string to contains-string
Removed support of having IsTextSearchEnabled enabled
Shows dropdown as soon one changes the search string, so search result is displayed
Example of how it is used:
<Controls:AutoFilteredComboBox ItemsSource="{Binding ViewModel.AvailableItems}"
SelectedValue="{Binding ViewModel.SelectedItem, Mode=TwoWay}"
IsEditable="True" IsTextSearchEnabled="False"/>
Improved version of AutoFilteredComboBox:
public class AutoFilteredComboBox : ComboBox
{
bool _ignoreTextChanged;
string _currentText;
/// <summary>
/// Creates a new instance of <see cref="AutoFilteredComboBox" />.
/// </summary>
public AutoFilteredComboBox()
{
if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) return;
}
public event Func<object, string, bool> FilterItem;
public event Action<string> FilterList;
#region IsCaseSensitive Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="IsCaseSensitive" /> dependency property.
/// </summary>
public static readonly DependencyProperty IsCaseSensitiveProperty =
DependencyProperty.Register("IsCaseSensitive", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box treats the case sensitivity of typed text.
/// </summary>
/// <value>The way the combo box treats the case sensitivity of typed text.</value>
[Description("The way the combo box treats the case sensitivity of typed text.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(true)]
public bool IsCaseSensitive
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(IsCaseSensitiveProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(IsCaseSensitiveProperty, value);
}
}
#endregion
#region DropDownOnFocus Dependency Property
/// <summary>
/// The <see cref="DependencyProperty"/> object of the <see cref="DropDownOnFocus" /> dependency property.
/// </summary>
public static readonly DependencyProperty DropDownOnFocusProperty =
DependencyProperty.Register("DropDownOnFocus", typeof(bool), typeof(AutoFilteredComboBox), new UIPropertyMetadata(false));
/// <summary>
/// Gets or sets the way the combo box behaves when it receives focus.
/// </summary>
/// <value>The way the combo box behaves when it receives focus.</value>
[Description("The way the combo box behaves when it receives focus.")]
[Category("AutoFiltered ComboBox")]
[DefaultValue(false)]
public bool DropDownOnFocus
{
[System.Diagnostics.DebuggerStepThrough]
get
{
return (bool)this.GetValue(DropDownOnFocusProperty);
}
[System.Diagnostics.DebuggerStepThrough]
set
{
this.SetValue(DropDownOnFocusProperty, value);
}
}
#endregion
#region | Handle focus |
/// <summary>
/// Invoked whenever an unhandled <see cref="UIElement.GotFocus" /> event
/// reaches this element in its route.
/// </summary>
/// <param name="e">The <see cref="RoutedEventArgs" /> that contains the event data.</param>
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (this.ItemsSource != null && this.DropDownOnFocus)
{
this.IsDropDownOpen = true;
}
}
#endregion
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
AddHandler(TextBox.TextChangedEvent, new TextChangedEventHandler(OnTextChanged));
KeyUp += AutoFilteredComboBox_KeyUp;
this.IsTextSearchEnabled = false;
}
void AutoFilteredComboBox_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Down)
{
if (this.IsDropDownOpen == true)
{
// Ensure that focus is given to the dropdown list
if (Keyboard.FocusedElement is TextBox)
{
Keyboard.Focus(this);
if (this.Items.Count > 0)
{
if (this.SelectedIndex == -1 || this.SelectedIndex==0)
this.SelectedIndex = 0;
}
}
}
}
if (Keyboard.FocusedElement is TextBox)
{
if (e.OriginalSource is TextBox)
{
// Avoid the automatic selection of the first letter (As next letter will cause overwrite)
TextBox textBox = e.OriginalSource as TextBox;
if (textBox.Text.Length == 1 && textBox.SelectionLength == 1)
{
textBox.SelectionLength = 0;
textBox.SelectionStart = 1;
}
}
}
}
#region | Handle filtering |
private void RefreshFilter()
{
if (this.ItemsSource != null)
{
Action<string> filterList = FilterList;
if (filterList != null)
{
filterList(_currentText);
}
else
{
ICollectionView view = CollectionViewSource.GetDefaultView(this.ItemsSource);
view.Refresh();
}
this.SelectedIndex = -1; // Prepare so arrow down selects first
this.IsDropDownOpen = true;
}
}
private bool FilterPredicate(object value)
{
// We don't like nulls.
if (value == null)
return false;
// If there is no text, there's no reason to filter.
if (string.IsNullOrEmpty(_currentText))
return true;
Func<object, string, bool> filterItem = FilterItem;
if (filterItem != null)
return filterItem(value, _currentText);
if (IsCaseSensitive)
return value.ToString().Contains(_currentText);
else
return value.ToString().ToUpper().Contains(_currentText.ToUpper());
}
#endregion
protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
try
{
_ignoreTextChanged = true; // Ignore the following TextChanged
base.OnSelectionChanged(e);
}
finally
{
_ignoreTextChanged = false;
}
}
/// <summary>
/// Called when the source of an item in a selector changes.
/// </summary>
/// <param name="oldValue">Old value of the source.</param>
/// <param name="newValue">New value of the source.</param>
protected override void OnItemsSourceChanged(IEnumerable oldValue, IEnumerable newValue)
{
if (newValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(newValue);
if (FilterList == null)
view.Filter += this.FilterPredicate;
}
if (oldValue != null)
{
ICollectionView view = CollectionViewSource.GetDefaultView(oldValue);
view.Filter -= this.FilterPredicate;
}
base.OnItemsSourceChanged(oldValue, newValue);
}
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
if (_ignoreTextChanged)
return;
_currentText = Text;
if (!this.IsTextSearchEnabled)
{
this.RefreshFilter();
}
}
I have found a super simple workaround to my problem.
i created a preview text input event of the combobox.
then i just wrote
Combobox.IsDropDownOpen = true
may not the most elegant but works in my case