Custom Checkbox Default Text Binding on Xamarin - c#

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;
}
}

Related

How to hide all the icons in the media player other than Play/Pause and Volume button?

I have a media player in which I want to hide the aspect ratio, cast to device and full screen icon in media player. This is the screenshot of my media player in which I have marked the icon which I need to hide in red color.
So I have taken this media player from this link. This is the my Xaml code
<StackLayout>
<Button Text="Stretch" Clicked="Button_Clicked"/>
<forms1:MediaElement HorizontalOptions="Fill" BackgroundColor="Green" VerticalOptions="Center" HeightRequest="180" x:Name="Media" IsLooping="True" AreTransportControlsEnabled="true" Source="http://video.ch9.ms/ch9/334f/891b78a5-642d-40b4-8d02-ff40ffdd334f/LoginToLinkedinUSingXamarinAuth_mid.mp4"/>
</StackLayout>
This is my media element code-
public sealed class MediaElement : View
{
/// <summary>
/// Identifies the AreTransportControlsEnabled dependency property.
/// </summary>
public static readonly BindableProperty AreTransportControlsEnabledProperty =
BindableProperty.Create(nameof(AreTransportControlsEnabled), typeof(bool), typeof(MediaElement), false);
/// <summary>
/// Identifies the AutoPlay dependency property.
/// </summary>
public static readonly BindableProperty AutoPlayProperty =
BindableProperty.Create(nameof(AutoPlay), typeof(bool), typeof(MediaElement), true);
/// <summary>
/// Identifies the BufferingProgress dependency property.
/// </summary>
public static readonly BindableProperty BufferingProgressProperty =
BindableProperty.Create(nameof(BufferingProgress), typeof(double), typeof(MediaElement), 0.0);
/// <summary>
/// Identifies the IsLooping dependency property.
/// </summary>
public static readonly BindableProperty IsLoopingProperty =
BindableProperty.Create(nameof(IsLooping), typeof(bool), typeof(MediaElement), false);
/// <summary>
/// Identifies the KeepScreenOn dependency property.
/// </summary>
public static readonly BindableProperty KeepScreenOnProperty =
BindableProperty.Create(nameof(KeepScreenOn), typeof(bool), typeof(MediaElement), false);
/// <summary>
/// Identifies the Source dependency property.
/// </summary>
public static readonly BindableProperty SourceProperty =
BindableProperty.Create(nameof(Source), typeof(Uri), typeof(MediaElement));
/// <summary>
/// Identifies the CurrentState dependency property.
/// </summary>
public static readonly BindableProperty CurrentStateProperty =
BindableProperty.Create(nameof(CurrentState), typeof(MediaElementState), typeof(MediaElement), MediaElementState.Closed);
/// <summary>
/// Identifies the Position dependency property.
/// </summary>
public static readonly BindableProperty PositionProperty =
BindableProperty.Create(nameof(Position), typeof(TimeSpan), typeof(MediaElement), TimeSpan.Zero, validateValue: ValidatePosition);
private static bool ValidatePosition(BindableObject bindable, object value)
{
MediaElement element = bindable as MediaElement;
if (element != null)
{
if (element._renderer != null)
{
element._renderer.Seek((TimeSpan)value);
}
}
return true;
}
/// <summary>
/// Identifies the Stretch dependency property.
/// </summary>
public static readonly BindableProperty StretchProperty =
BindableProperty.Create(nameof(Stretch), typeof(Stretch), typeof(MediaElement), Stretch.Uniform);
private IMediaElementRenderer _renderer = null;
public void SetRenderer(IMediaElementRenderer renderer)
{
_renderer = renderer;
}
/// <summary>
/// Gets or sets a value that determines whether the standard transport controls are enabled.
/// </summary>
public bool AreTransportControlsEnabled
{
get { return (bool)GetValue(AreTransportControlsEnabledProperty); }
set { SetValue(AreTransportControlsEnabledProperty, value); }
}
/// <summary>
/// Gets or sets a value that indicates whether media will begin playback automatically when the <see cref="Source"/> property is set.
/// </summary>
public bool AutoPlay
{
get { return (bool)GetValue(AutoPlayProperty); }
set { SetValue(AutoPlayProperty, value); }
}
/// <summary>
/// Gets a value that indicates the current buffering progress.
/// </summary>
/// <value>The amount of buffering that is completed for media content.
/// The value ranges from 0 to 1.
/// Multiply by 100 to obtain a percentage.</value>
public double BufferingProgress
{
get
{
return (double)GetValue(BufferingProgressProperty);
}
}
/// <summary>
/// Gets or sets a value that describes whether the media source currently loaded in the media engine should automatically set the position to the media start after reaching its end.
/// </summary>
public bool IsLooping
{
get { return (bool)GetValue(IsLoopingProperty); }
set { SetValue(IsLoopingProperty, value); }
}
/// <summary>
/// Gets or sets a value that specifies whether the control should stop the screen from timing out when playing media.
/// </summary>
public bool KeepScreenOn
{
get { return (bool)GetValue(KeepScreenOnProperty); }
set { SetValue(KeepScreenOnProperty, value); }
}
public TimeSpan NaturalDuration
{
get
{
if (_renderer != null)
{
return _renderer.NaturalDuration;
}
return TimeSpan.Zero;
}
}
public int NaturalVideoHeight
{
get
{
if (_renderer != null)
{
return _renderer.NaturalVideoHeight;
}
return 0;
}
}
public int NaturalVideoWidth
{
get
{
if (_renderer != null)
{
return _renderer.NaturalVideoWidth;
}
return 0;
}
}
/// <summary>
/// Gets or sets a media source on the MediaElement.
/// </summary>
[TypeConverter(typeof(Xamarin.Forms.UriTypeConverter))]
public Uri Source
{
get { return (Uri)GetValue(SourceProperty); }
set { SetValue(SourceProperty, value); }
}
private IDictionary<string, string> _httpHeaders = new Dictionary<string, string>();
public IDictionary<string, string> HttpHeaders
{
get
{
return _httpHeaders;
}
}
/// <summary>
/// Gets the status of this MediaElement.
/// </summary>
public MediaElementState CurrentState
{
get { return (MediaElementState)GetValue(CurrentStateProperty); }
internal set
{
SetValue(CurrentStateProperty, value);
}
}
public void RaiseCurrentStateChanged()
{
CurrentStateChanged?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Gets or sets the current position of progress through the media's playback time.
/// </summary>
public System.TimeSpan Position
{
get
{
if (_renderer != null)
{
return _renderer.Position;
}
return (TimeSpan)GetValue(PositionProperty);
}
set
{
SetValue(PositionProperty, value);
}
}
/// <summary>
/// Plays media from the current position.
/// </summary>
public void Play()
{
CurrentState = MediaElementState.Playing;
}
/// <summary>
/// Pauses media at the current position.
/// </summary>
public void Pause()
{
if (CurrentState == MediaElementState.Playing)
{
CurrentState = MediaElementState.Paused;
}
}
/// <summary>
/// Stops and resets media to be played from the beginning.
/// </summary>
public void Stop()
{
if (CurrentState != MediaElementState.Stopped)
{
CurrentState = MediaElementState.Stopped;
}
}
/// <summary>
/// Gets or sets a value that describes how an MediaElement should be stretched to fill the destination rectangle.
/// </summary>
/// <value>A value of the <see cref="Stretch"/> enumeration that specifies how the source visual media is rendered.
/// The default value is Uniform.</value>
public Stretch Stretch
{
get
{
return (Stretch)GetValue(StretchProperty);
}
set
{
SetValue(StretchProperty, value);
}
}
/// <summary>
/// Occurs when the value of the <see cref="CurrentState"/> property changes.
/// </summary>
public event EventHandler CurrentStateChanged;
/// <summary>
/// Occurs when the MediaElement finishes playing audio or video.
/// </summary>
public event EventHandler MediaEnded;
public void RaiseMediaOpened()
{
MediaOpened?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Occurs when the media stream has been validated and opened, and the file headers have been read.
/// </summary>
public event EventHandler MediaOpened;
public void RaiseSeekCompleted()
{
SeekCompleted?.Invoke(this, EventArgs.Empty);
}
/// <summary>
/// Occurs when the seek point of a requested seek operation is ready for playback.
/// </summary>
public event EventHandler SeekCompleted;
public void OnMediaEnded()
{
CurrentState = MediaElementState.Stopped;
if (MediaEnded != null)
{
System.Diagnostics.Debug.WriteLine("Media Ended");
MediaEnded(this, EventArgs.Empty);
}
}
internal void RaisePropertyChanged(string propertyName)
{
OnPropertyChanged(propertyName);
}
}
public interface IMediaElementRenderer
{
double BufferingProgress { get; }
TimeSpan NaturalDuration { get; }
int NaturalVideoHeight { get; }
int NaturalVideoWidth { get; }
TimeSpan Position { get; }
void Seek(TimeSpan time);
}
}
I don't have any clue how hide those icons. Any suggestions?

Background image throws exception when used in custom editor

I am using custom editor collection for a property(which contains the collection of custom controls) in custom control. I have used the UITypeEditor for this property as given in this link . Now when clicking the property, UI editors shows but when clicking the background image it shows the following error.
Background image throws exception when used in custom editor
Can anyone please help me to resolve this?
Here is my property
/// <summary>
/// Gets or sets the value to the items of the the TreeNavigator.
/// </summary>
[Browsable(true), DefaultValue(null),
Category("Appearance"), Description("Gets or sets the value to the items of the Custom control.")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
[TypeConverter(typeof(ItemConverter))]
[Editor(typeof(ItemCustomCollectionEditor), typeof(UITypeEditor))]
public MenuItemCollection Items
{
get
{
if (items == null)
{
items = new MenuItemCollection((this.Parent.Parent as CustomControl));
}
return items;
}
set
{
if (items != value)
{
items = value;
PerformLayout();
}
}
}
and this my custom editor
public class ItemCustomCollectionEditor : System.Drawing.Design.UITypeEditor
{
/// <summary>
/// delegate for collection changed event
/// </summary>
public delegate void CollectionChangedEventHandler(object sender, object instance, object value);
/// <summary>
/// Fires when the Collection in the item changes
/// </summary>
public event CollectionChangedEventHandler CollectionChanged;
/// <summary>
/// ITypeDescriptorContext
/// </summary>
private ITypeDescriptorContext _context;
/// <summary>
/// IWindowsFormsEditorService
/// </summary>
private IWindowsFormsEditorService edSvc = null;
/// <summary>
/// ItemCustomCollectionEditor constructor
/// </summary>
public ItemCustomCollectionEditor()
{ }
/// <summary>
/// EditVaue method is used to edit the value in the Item Collection
/// </summary>
/// <param name="context">Provides information about container</param>
/// <param name="provider">Object providing custom support</param>
/// <param name="value">Object of the container</param>
/// <returns>Returns the object of the container</returns>
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
Menuitemcollection coll = value as Menuitemcollection;
CustomControl owner = coll.container;
if (context != null && context.Instance != null && provider != null)
{
object originalValue = value;
_context = context;
if (provider != null)
{
edSvc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
}
if (edSvc != null)
{
ItemCollectionEditorForm collEditorFrm = CreateForm(owner);
collEditorFrm.ItemAdded += new ItemCollectionEditorForm.InstanceEventHandler(ItemAdded);
collEditorFrm.ItemRemoved += new ItemCollectionEditorForm.InstanceEventHandler(ItemRemoved);
collEditorFrm.Collection = (IList)value;
context.OnComponentChanging();
if (edSvc.ShowDialog(collEditorFrm) == DialogResult.OK)
{
OnCollectionChanged(context.Instance, value);
context.OnComponentChanged();
value = collEditorFrm.Collection;
}
}
}
return value;
}
/// <summary>
/// GetEditStyle for the editor
/// </summary>
/// <param name="context">Provides information about container</param>
/// <returns>Returns EditorStyle</returns>
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
if (context != null && context.Instance != null)
{
return UITypeEditorEditStyle.Modal;
}
return UITypeEditorEditStyle.Modal;
}
/// <summary>
/// Indicates the ItemAdded
/// </summary>
/// <param name="sender">Sender as container</param>
/// <param name="item">Added Items in the container</param>
private void ItemAdded(object sender, object item)
{
if (_context != null && _context.Container != null)
{
IComponent icomp = item as IComponent;
if (icomp != null)
{
_context.Container.Add(icomp);
}
}
}
/// <summary>
/// Indicates the ItemAdded
/// </summary>
/// <param name="sender">Sender as container</param>
/// <param name="item">Added Items in the container</param>
private void ItemRemoved(object sender, object item)
{
if (_context != null && _context.Container != null)
{
IComponent icomp = item as IComponent;
if (icomp != null)
{
_context.Container.Remove(icomp);
}
}
}
/// <summary>
/// Triggers the CollectionChanged event
/// </summary>
/// <param name="instance">Object that carries the Item</param>
/// <param name="value">Value of the Item with all its associated properties</param>
protected virtual void OnCollectionChanged(object instance, object value)
{
if (CollectionChanged != null)
{
CollectionChanged(this, instance, value);
}
}
/// <summary>
/// Creates the form
/// </summary>
/// <param name="owner">CustomControl Form</param>
/// <returns>Returns the new CollectionEditorForm</returns>
protected virtual ItemCollectionEditorForm CreateForm(CustomControl owner)
{
return new ItemCollectionEditorForm(owner);
}
}

WPF button property on user control not showing properties in property pane

I've been beating my head against the wall over this for days now and I can't seem to find any info that fits my problem.
So, I have this toolbar Usercontrol that's meant to be dropped in to an application. This toolbar has a property exposed called "FullExtentButton" which is a reference to the button. What I want is to expose the properties of this button in the designer properties pane on the toolbar user control so the developers can set the properties directly from the designer.
In WinForms, this was very easy to do. WPF, not so much (unless I'm just blind).
In my tool bar code:
[Category("Standard Buttons")]
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public MyToolbarButton FullExtentButton
{
get;
private set;
}
This value is set in the constructor the user control:
public MyToolbar()
{
InitializeComponent();
FullExtentButton = new MyToolbarButton("FullExtent", "/Utilities;component/Resources/full_extent_16x16.png");
}
The button itself is quite simple:
public class MyToolbarButton
: Freezable
{
#region Dependency Properties.
/// <summary>
/// Dependency property for the <see cref="IsVisible"/> property.
/// </summary>
public static DependencyProperty IsVisibleProperty = DependencyProperty.Register("IsVisible", typeof(bool), typeof(MyToolbarButton),
new FrameworkPropertyMetadata(true,
FrameworkPropertyMetadataOptions
.BindsTwoWayByDefault, Visible_Changed));
/// <summary>
/// Dependency property for the <see cref="IsEnabled"/> property.
/// </summary>
public static DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(MyToolbarButton),
new FrameworkPropertyMetadata(true,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Enabled_Changed));
/// <summary>
/// Dependency property for the <see cref="ToolTip"/> property.
/// </summary>
public static DependencyProperty ToolTipProperty = DependencyProperty.Register("ToolTip", typeof(string), typeof(MyToolbarButton),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, ToolTip_Changed));
/// <summary>
/// Dependency property for the <see cref="Glyph"/> property.
/// </summary>
public static DependencyProperty GlyphProperty = DependencyProperty.Register("Glyph", typeof(ImageSource), typeof(MyToolbarButton),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Glyph_Changed));
/// <summary>
/// Dependency property for the <see cref="ID"/> property.
/// </summary>
public static DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(string), typeof(MyToolbarButton),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
/// <summary>
/// Dependency property for the <see cref="ClickedCommand"/> property.
/// </summary>
public static DependencyProperty ClickedCommandProperty = DependencyProperty.Register("ClickedCommand", typeof(IMyRelayCommand<string>),
typeof(MyToolbarButton),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
#endregion
#region Variables.
// The default image source for the button glyph.
private readonly Uri _defaultImageSource;
#endregion
#region Properties.
/// <summary>
/// Property to set or return the command to execute when the button is clicked.
/// </summary>
public IMyRelayCommand<string> ClickedCommand
{
get
{
return (IMyRelayCommand<string>)GetValue(ClickedCommandProperty);
}
set
{
SetValue(ClickedCommandProperty, value);
}
}
/// <summary>
/// Property to set or return the ID of the button.
/// </summary>
public string ID
{
get
{
object value = GetValue(IDProperty);
return value == null ? string.Empty : value.ToString();
}
set
{
SetValue(IDProperty, value);
}
}
/// <summary>
/// Property to set or return the glyph for this button.
/// </summary>
public ImageSource Glyph
{
get
{
return GetValue(GlyphProperty) as ImageSource;
}
set
{
SetValue(GlyphProperty, value);
}
}
/// <summary>
/// Property to set or return the tool tip for the button.
/// </summary>
public string ToolTip
{
get
{
object value = GetValue(ToolTipProperty);
return value == null ? string.Empty : value.ToString();
}
set
{
SetValue(ToolTipProperty, value);
}
}
/// <summary>
/// Property to set or return whether the button is visible or not.
/// </summary>
public bool IsVisible
{
get
{
return (bool)GetValue(IsVisibleProperty);
}
set
{
SetValue(IsVisibleProperty, value);
}
}
/// <summary>
/// Property to set or return whether the button is enabled or not.
/// </summary>
public bool IsEnabled
{
get
{
return (bool)GetValue(IsEnabledProperty);
}
set
{
SetValue(IsEnabledProperty, value);
}
}
#endregion
#region Methods.
/// <summary>
/// Function to handle a change to the <see cref="GlyphProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Glyph_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// Function to handle a change to the <see cref="IsVisibleProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Visible_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// Function to handle a change to the <see cref="IsEnabledProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// When implemented in a derived class, creates a new instance of the <see cref="T:System.Windows.Freezable" /> derived class.
/// </summary>
/// <returns>The new instance.</returns>
protected override Freezable CreateInstanceCore()
{
return new MyToolbarButton();
}
#endregion
#region Constructor/Finalizer.
/// <summary>
/// Initializes a new instance of the <see cref="MyToolbarButton"/> class.
/// </summary>
/// <param name="buttonID">The ID of the button being clicked.</param>
/// <param name="defaultImageSource">The default image source URI for the glyph used by the button.</param>
internal MyToolbarButton(string buttonID, string defaultImageSource)
{
ID = buttonID;
IsVisible = true;
IsEnabled = true;
ToolTip = string.Empty;
if (!string.IsNullOrWhiteSpace(defaultImageSource))
{
_defaultImageSource = new Uri(defaultImageSource, UriKind.Relative);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="MyToolbarButton"/> class.
/// </summary>
public MyToolbarButton()
{
// This is here to keep the XAML designer from complaining.
}
#endregion
But, when I view the button property on my user control in the XAML designer, and expand its properties I get this:
As you can see, there are no properties under that property in the XAML designer. What I want is to have the properties for that button appear under the "FullExtentsButton" property so that my developers can modify the properties, but not be able to create/remove the instance that's already there.
I've tried making the FullExtentButton property on my UserControl a DependencyProperty, but that didn't fix anything.
This is part of a standard toolbar that we want to use across applications, so enforcing consistency is pretty important for us. Plus it will allow our devs to focus on other parts of applications rather than reimplementing the same thing over and over (which is what we're having to do right now).
So, that said, I'm at my wits end here, what am I doing wrong?
Using this code which I had to change somewhat to get it to compile....
/// <summary>
/// Interaction logic for MyToolBarButton.xaml
/// </summary>
public partial class MyToolBarButton : UserControl
{
public MyToolBarButton()
{
InitializeComponent();
}
#region Dependency Properties.
/// <summary>
/// Dependency property for the <see cref="IsVisible"/> property.
/// </summary>
public static DependencyProperty IsVisibleProperty = DependencyProperty.Register("IsVisible", typeof(bool), typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(true,
FrameworkPropertyMetadataOptions
.BindsTwoWayByDefault, Visible_Changed));
/// <summary>
/// Dependency property for the <see cref="IsEnabled"/> property.
/// </summary>
public static DependencyProperty IsEnabledProperty = DependencyProperty.Register("IsEnabled", typeof(bool), typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(true,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Enabled_Changed));
/// <summary>
/// Dependency property for the <see cref="ToolTip"/> property.
/// </summary>
public static DependencyProperty ToolTipProperty = DependencyProperty.Register("ToolTip", typeof(string), typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault,
new PropertyChangedCallback(ToolTipPropertyChanged)));
private static void ToolTipPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
throw new NotImplementedException();
}
/// <summary>
/// Dependency property for the <see cref="Glyph"/> property.
/// </summary>
public static DependencyProperty GlyphProperty = DependencyProperty.Register("Glyph", typeof(ImageSource), typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(null,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, Glyph_Changed));
/// <summary>
/// Dependency property for the <see cref="ID"/> property.
/// </summary>
public static DependencyProperty IDProperty = DependencyProperty.Register("ID", typeof(string), typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(string.Empty,
FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
/// <summary>
/// Dependency property for the <see cref="ClickedCommand"/> property.
/// </summary>
public static DependencyProperty ClickedCommandProperty = DependencyProperty.Register("ClickedCommand", typeof(string),
typeof(MyOldToolBarButton),
new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
#endregion
#region Variables.
// The default image source for the button glyph.
public Uri _defaultImageSource { private set; get; }
#endregion
#region Properties.
/// <summary>
/// Property to set or return the ID of the button.
/// </summary>
[Category("Configuration")]
public string ID
{
get
{
object value = GetValue(IDProperty);
return value == null ? string.Empty : value.ToString();
}
set
{
SetValue(IDProperty, value);
}
}
/// <summary>
/// Property to set or return the glyph for this button.
/// </summary>
[Category("Configuration")]
public ImageSource Glyph
{
get
{
return GetValue(GlyphProperty) as ImageSource;
}
set
{
SetValue(GlyphProperty, value);
}
}
/// <summary>
/// Property to set or return the tool tip for the button.
/// </summary>
///
[Category("Configuration")]
public string ToolTip
{
get
{
object value = GetValue(ToolTipProperty);
return value == null ? string.Empty : value.ToString();
}
set
{
SetValue(ToolTipProperty, value);
}
}
/// <summary>
/// Property to set or return whether the button is visible or not.
/// </summary>
///
[Category("Configuration")]
public bool IsVisible
{
get
{
return (bool)GetValue(IsVisibleProperty);
}
set
{
SetValue(IsVisibleProperty, value);
}
}
/// <summary>
/// Property to set or return whether the button is enabled or not.
/// </summary>
///
[Category("Configuration")]
public bool IsEnabled
{
get
{
return (bool)GetValue(IsEnabledProperty);
}
set
{
SetValue(IsEnabledProperty, value);
}
}
#endregion
#region Methods.
/// <summary>
/// Function to handle a change to the <see cref="GlyphProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Glyph_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// Function to handle a change to the <see cref="IsVisibleProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Visible_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// Function to handle a change to the <see cref="IsEnabledProperty"/>.
/// </summary>
/// <param name="sender">The sender of the event.</param>
/// <param name="e">The <see cref="DependencyPropertyChangedEventArgs"/> instance containing the event data.</param>
private static void Enabled_Changed(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
// TODO
}
/// <summary>
/// When implemented in a derived class, creates a new instance of the <see cref="T:System.Windows.Freezable" /> derived class.
/// </summary>
/// <returns>The new instance.</returns>
protected Freezable CreateInstanceCore()
{
return new MyOldToolBarButton();
}
#endregion
#region Constructor/Finalizer.
/// <summary>
/// Initializes a new instance of the <see cref="MyOldToolBarButton"/> class.
/// </summary>
/// <param name="buttonID">The ID of the button being clicked.</param>
/// <param name="defaultImageSource">The default image source URI for the glyph used by the button.</param>
internal void MyOldToolBarButton(string buttonID, string defaultImageSource)
{
ID = buttonID;
IsVisible = true;
IsEnabled = true;
ToolTip = string.Empty;
if (!string.IsNullOrWhiteSpace(defaultImageSource))
{
_defaultImageSource = new Uri(defaultImageSource, UriKind.Relative);
}
}
/// <summary>
/// Initializes a new instance of the <see cref="MyOldToolBarButton"/> class.
/// </summary>
public void MyOldToolBarButton()
{
// This is here to keep the XAML designer from complaining.
}
#endregion
}
And adding it to another "parent" control... The properties look like this:
Is this what you are looking for?

ContentDialog do not subscribe to ICommand.CanExecuteChanged

I have a problem with Windows.UI.Xaml.Controls.ContentDialog. I want to disable it primary button when System.Windows.Input.ICommand.CanExecute return false. But it seem ContentDialog does not subscribe to ICommand.CanExecuteChanged event. I don't known why. This is my code:
NewTracingDialog.xaml
<ContentDialog
x:Class="RouterTracer.NewTracingDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:RouterTracer"
xmlns:model="using:RouterTracer.ViewModels"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="NEW TRACING"
PrimaryButtonText="trace"
SecondaryButtonText="cancel"
PrimaryButtonCommand="{Binding}"
d:DataContext="{d:DesignInstance Type=model:NewTracingViewModel}">
<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<TextBox Name="destinationHost" Header="Destination Host" Text="{Binding Host, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Name="port" Header="UDP Port" InputScope="Number" Text="{Binding Port, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
<TextBox Name="hopLimit" Header="Hop Limit" InputScope="Number" Text="{Binding HopLimit, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</ContentDialog>
NewTracingViewModel.cs
//-----------------------------------------------------------------------
// <copyright file="NewTracingViewModel.cs">
// Copyright (c) Putta Khunchalee.
// </copyright>
// <author>Putta Khunchalee</author>
//-----------------------------------------------------------------------
namespace RouterTracer.ViewModels
{
using System;
/// <summary>
/// View model for new tracing dialog.
/// </summary>
public sealed class NewTracingViewModel : ExecutableViewModel
{
private byte hopLimit;
private string host;
private ushort port;
/// <summary>
/// Initialize a new instance of the <see cref="NewTracingViewModel"/> class.
/// </summary>
public NewTracingViewModel()
{
}
/// <summary>
/// Gets or sets TTL or Hop Limit.
/// </summary>
/// <value>
/// TTL or Hop Limit.
/// </value>
public byte HopLimit
{
get { return this.hopLimit; }
set { this.SetProperty(ref this.hopLimit, value, "HopLimit"); }
}
/// <summary>
/// Gets or sets destination host.
/// </summary>
/// <value>
/// Hestination host.
/// </value>
public string Host
{
get { return this.host; }
set { this.SetProperty(ref this.host, value, "Host"); }
}
/// <summary>
/// Gets or sets destination port.
/// </summary>
/// <value>
/// Destination port.
/// </value>
public ushort Port
{
get { return this.port; }
set { this.SetProperty(ref this.port, value, "Port"); }
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">
/// Data used by the command. If the command does not require data to be passed,
/// this object can be set to <c>null</c>.
/// </param>
public override void Execute(object parameter)
{
// This method get execute normally.
}
/// <summary>
/// Validate all properties to determine executable status.
/// </summary>
/// <returns>
/// <c>true</c> if instance can be execute; otherwise <c>false</c>.
/// </returns>
protected override bool ValidateProperties()
{
if (this.hopLimit == 0)
{
return false;
}
if (string.IsNullOrWhiteSpace(this.host))
{
return false;
}
if (this.port == 0)
{
return false;
}
return true;
}
}
}
ExecutableViewModel.cs
//-----------------------------------------------------------------------
// <copyright file="ExecutableViewModel.cs">
// Copyright (c) Putta Khunchalee.
// </copyright>
// <author>Putta Khunchalee</author>
//-----------------------------------------------------------------------
namespace RouterTracer.ViewModels
{
using System;
using System.Windows.Input;
/// <summary>
/// Base class for all View Model that executable via <see cref="ICommand"/>.
/// </summary>
public abstract class ExecutableViewModel : ViewModel, ICommand
{
private bool canExecute;
/// <summary>
/// Initialize a new instance of the <see cref="ExecutableViewModel"/> class.
/// </summary>
protected ExecutableViewModel()
{
}
/// <summary>
/// Occurs when changes occur that affect whether or not the command should execute.
/// </summary>
public event EventHandler CanExecuteChanged;
/// <summary>
/// Defines the method that determines whether the command can execute in its current state.
/// </summary>
/// <param name="parameter">
/// Data used by the command. If the command does not require data to be passed,
/// this object can be set to <c>null</c>.
/// </param>
/// <returns>
/// <c>true</c> if this command can be executed; otherwise, <c>false</c>.
/// </returns>
public bool CanExecute(object parameter)
{
return this.canExecute;
}
/// <summary>
/// Defines the method to be called when the command is invoked.
/// </summary>
/// <param name="parameter">
/// Data used by the command. If the command does not require data to be passed,
/// this object can be set to <c>null</c>.
/// </param>
public abstract void Execute(object parameter);
/// <summary>
/// Invoked when status of <see cref="CanExecute(object)"/> has changed.
/// </summary>
protected virtual void OnCanExecuteChanged()
{
var handlers = this.CanExecuteChanged;
if (handlers != null)
{
handlers(this, EventArgs.Empty);
}
}
/// <summary>
/// Invoked when value of model's property has been changed.
/// </summary>
/// <param name="name">
/// Name of the property that value has changed.
/// </param>
protected override void OnPropertyChanged(string name)
{
base.OnPropertyChanged(name);
this.UpdateCanExecuteFlag(ValidateProperties());
}
/// <summary>
/// Validate all properties to determine executable status.
/// </summary>
/// <returns>
/// <c>true</c> if instance can be execute; otherwise <c>false</c>.
/// </returns>
protected abstract bool ValidateProperties();
/// <summary>
/// Update status of <see cref="CanExecute(object)"/>.
/// </summary>
/// <param name="canExecute">
/// <c>true</c> if instance can be execute; otherwise <c>false</c>.
/// </param>
private void UpdateCanExecuteFlag(bool canExecute)
{
if (this.canExecute == canExecute)
{
return;
}
this.canExecute = canExecute;
this.OnCanExecuteChanged();
}
}
}
ViewModel.cs
//-----------------------------------------------------------------------
// <copyright file="ViewModel.cs">
// Copyright (c) Putta Khunchalee.
// </copyright>
// <author>Putta Khunchalee</author>
//-----------------------------------------------------------------------
namespace RouterTracer.ViewModels
{
using System.ComponentModel;
/// <summary>
/// Base class for all View Model.
/// </summary>
public abstract class ViewModel : INotifyPropertyChanged
{
/// <summary>
/// Initialize a new instance of the <see cref="ViewModel"/> class.
/// </summary>
protected ViewModel()
{
}
/// <summary>
/// Raise when value of model's property has been changed.
/// </summary>
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Invoked when value of model's property has been changed.
/// </summary>
/// <param name="name">
/// Name of the property that value has changed.
/// </param>
protected virtual void OnPropertyChanged(string name)
{
var handlers = this.PropertyChanged;
if (handlers != null)
{
handlers(this, new PropertyChangedEventArgs(name));
}
}
/// <summary>
/// Change the value of the field that is property backed.
/// </summary>
/// <typeparam name="T">
/// Type of the field.
/// </typeparam>
/// <param name="field">
/// Field to change value.
/// </param>
/// <param name="value">
/// The new value.
/// </param>
/// <param name="name">
/// Name of backed property.
/// </param>
/// <returns>
/// <c>true</c> when value has been changed; otherwise <c>false</c>.
/// </returns>
protected bool SetProperty<T>(ref T field, T value, string name)
{
T previousValue;
// Check to see if value change is neccessary.
if (object.Equals(field, value))
{
return false;
}
// Change value.
previousValue = field;
field = value;
this.OnPropertyChanged(name);
return true;
}
}
}
Sorry for long codes. Thank you.
I have give up and use a workaround instead. Maybe it is not yet implemented in ContentDialog. This is my workaround.
NewTracingDialog.xaml.cs
//-----------------------------------------------------------------------
// <copyright file="NewTracingDialog.xaml.cs">
// Copyright (c) Putta Khunchalee.
// </copyright>
// <author>Putta Khunchalee</author>
//-----------------------------------------------------------------------
namespace RouterTracer
{
using System;
using System.Windows.Input;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
/// <summary>
/// Dialog for gather tracing information from user.
/// </summary>
public sealed partial class NewTracingDialog : ContentDialog
{
/// <summary>
/// Used to remove <see cref="OnDataContextCanExecuteChanged(object, EventArgs)"/> before
/// changing to the new data context.
/// </summary>
private ICommand currentDataContext;
/// <summary>
/// Initialize a new instance of the <see cref="NewTracingDialog"/> class.
/// </summary>
public NewTracingDialog()
{
this.InitializeComponent();
this.DataContextChanged += this.OnDataContextChanged;
}
/// <summary>
/// Invoke when executable flag of data context has changed.
/// </summary>
/// <param name="sender">
/// Data context that executable flag has changed.
/// </param>
/// <param name="e">
/// The empty <see cref="EventArgs"/>.
/// </param>
private void OnDataContextCanExecuteChanged(object sender, EventArgs e)
{
this.IsPrimaryButtonEnabled = ((ICommand)sender).CanExecute(null);
}
/// <summary>
/// Invoke when data context has been changed.
/// </summary>
/// <param name="sender">
/// The instance of <see cref="NewTracingDialog"/> that data context has changed.
/// </param>
/// <param name="args">
/// Event informations.
/// </param>
private void OnDataContextChanged(FrameworkElement sender, DataContextChangedEventArgs args)
{
// Get a new data context.
var command = (ICommand)args.NewValue;
if (command == null)
{
return;
}
// Disable primary button if data context is not executable.
this.IsPrimaryButtonEnabled = command.CanExecute(null);
// Subscribe to data context executable changed event.
if (this.currentDataContext != null)
{
this.currentDataContext.CanExecuteChanged -= this.OnDataContextCanExecuteChanged;
}
command.CanExecuteChanged += this.OnDataContextCanExecuteChanged;
this.currentDataContext = command;
}
}
}

Hub Tiles (In App Tiles) Windows Phone 8.1 (Universal Apps)

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.

Categories