/*
Copyright (C) 2008 Webyog Softworks Private Limited
This file is a part of Visifire Charts.
Visifire is a free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
You should have received a copy of the GNU General Public License
along with Visifire Charts. If not, see .
If GPL is not suitable for your products or company, Webyog provides Visifire
under a flexible commercial license designed to meet your specific usage and
distribution requirements. If you have already obtained a commercial license
from Webyog, you can use this file under those license terms.
*/
using System;
using System.Windows;
using System.Windows.Controls;
using System.Collections.Generic;
using System.Windows.Input;
using System.Windows.Media;
using System.ComponentModel;
using Visifire.Charts;
using System.Linq;
using System.Globalization;
using System.Windows.Data;
namespace Visifire.Commons
{
///
/// ObservableObject Implements INotifyPropertyChanged Interface
///
public abstract class ObservableObject : VisifireElement, INotifyPropertyChanged
{
///
/// Initializes a new instance of the Visifire.Commons.ObservableObject class
///
public ObservableObject()
: base()
{
// Attach event handler with EventChanged event of VisifireElement
// But do not attach the event for PlotArea beacuse PlotArea has overridden EventChanged as internal event
if (!this.GetType().Equals(typeof(PlotArea)))
{
// Attach event handler with EventChanged event of VisifireElement
EventChanged += delegate
{
FirePropertyChanged("MouseEvent");
};
}
IsNotificationEnable = true;
#if SL
Binding binding = new Binding("Style");
binding.Source = this;
binding.Mode = BindingMode.TwoWay;
this.SetBinding(ObservableObject.InternalStyleProperty, binding);
#endif
}
#region Public Methods
///
/// Apply specific style from theme
///
/// Control
/// Style key name
public void ApplyStyleFromTheme(VisifireControl control, String keyName)
{
bool oldIsNotificationEnable = IsNotificationEnable;
IsNotificationEnable = false;
Chart chart = control as Chart;
if (chart.StyleDictionary != null)
{
//#if SL
// if (Style == null)
// {
// Style myStyle = chart.StyleDictionary[keyName] as Style;
// if (myStyle != null)
// Style = myStyle;
// }
//#else
Style myStyle = chart.StyleDictionary[keyName] as Style;
System.Diagnostics.Debug.WriteLine(keyName);
if (myStyle != null)
{
if((Chart as Chart)._isThemeChanged)
Style = myStyle;
else if(Style == null)
Style = myStyle;
}
//#endif
}
IsNotificationEnable = oldIsNotificationEnable;
}
#endregion
#region Public Properties
///
/// Visifire Control reference
///
#if SL
[System.Windows.Browser.ScriptableMember]
#else
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
#endif
public VisifireControl Chart
{
get;
set;
}
///
/// Get or set the ToolTipText for the DataPoint
///
public override String ToolTipText
{
get
{
if ((Chart != null && !String.IsNullOrEmpty((Chart as Chart).ToolTipText)))
return null;
else
return (String)GetValue(ToolTipTextProperty);
}
set
{
SetValue(ToolTipTextProperty, value);
}
}
#endregion
#region Public Event
///
/// Event PropertyChanged will be fired if any property is changed
///
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region Protected Methods
///
/// UpdateVisual is used for partial rendering
///
/// Name of the property
/// Value of the property
internal virtual void UpdateVisual(String propertyName, object value)
{
}
///
/// Check whether the Property value is changed
///
/// Type
/// Property Name
/// Old property value
/// New property value
///
protected bool CheckPropertyChanged(string propertyName, ref T oldValue, ref T newValue)
{
if (oldValue == null && newValue == null)
{
return false;
}
if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
{
oldValue = newValue;
FirePropertyChanged(propertyName);
return true;
}
return false;
}
public virtual void Bind()
{
}
///
/// Fire property change event
///
/// Property Name
internal void FirePropertyChanged(string propertyName)
{
_isPropertyChangedFired = false; // Used for testing
if (this.PropertyChanged != null && this.IsNotificationEnable)
{
#if SL
if (IsInDesignMode)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
else if (Chart != null && (Chart as Chart)._isTemplateApplied)
{
if (Application.Current != null && Application.Current.RootVisual != null && Application.Current.RootVisual.Dispatcher != null)
{
System.Windows.Threading.Dispatcher currentDispatcher = Application.Current.RootVisual.Dispatcher;
if (currentDispatcher.CheckAccess())
(Chart as Chart).InvokeRender();
else
currentDispatcher.BeginInvoke(new Action(FirePropertyChanged), propertyName);
}
else // if we did not get the Dispatcher throw an exception
{
throw new InvalidOperationException("This object must be initialized after that the RootVisual has been loaded");
}
_isPropertyChangedFired = true; // Used for testing
}
#else
if (Chart != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
#endif
}
}
#endregion
#region Internal Properties
#if WPF
///
/// Whether the application is in design mode
///
internal Boolean IsInDesignMode
{
get
{
return System.ComponentModel.DesignerProperties.GetIsInDesignMode(this);
}
}
#else
///
/// Whether the application is in design mode
///
internal static Boolean IsInDesignMode
{
get
{
return !System.Windows.Browser.HtmlPage.IsEnabled;
}
}
#endif
#endregion
#region Private Delegates
#endregion
#region Private Methods
#endregion
#region Private Properties
#if WPF
///
/// Overrides the tooltip property of control
///
private new String ToolTip
{
get;
set;
}
#endif
#if SL
private static readonly DependencyProperty InternalStyleProperty = DependencyProperty.Register
("Style",
typeof(Style),
typeof(ObservableObject),
new PropertyMetadata(OnInternalStylePropertyChanged));
private static void OnInternalStylePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
ObservableObject obj = d as ObservableObject;
//Style style = (Style)e.NewValue;
//Boolean is2Break =false;
//foreach (Setter setter in obj.Style.Setters)
//{
// if (setter == null)
// return;
// switch (setter.Property.ToString())
// {
// case "FontWeight":
// obj.UpdateVisual("FontWeight", e.NewValue);
// break;
// case "FontStyle":
// obj.UpdateVisual("FontWeight", e.NewValue);
// break;
// default:
// is2Break = true;
// obj.FirePropertyChanged("Style");
// break;
// }
// if (is2Break)
// break;
//}
obj.Bind();
// obj.FirePropertyChanged("Style");
}
#endif
#endregion
#region Internal Property
///
/// Property change event will be fired if value is True
///
internal Boolean IsNotificationEnable
{
get;
set;
}
#endregion
#region Internal Methods
///
/// Formats newline character
///
/// Text
/// Formated Text
internal static String GetFormattedMultilineText(String text)
{
if (String.IsNullOrEmpty(text))
return "";
String[] split = { "\\n" };
String[] lines = text.Split(split, StringSplitOptions.RemoveEmptyEntries);
String multiLineText = "";
foreach (String line in lines)
{
if (line.EndsWith("\\"))
{
multiLineText += line + "n";
}
else
{
multiLineText += line + "\n";
}
}
if (text.EndsWith("\\n"))
return multiLineText;
else
return multiLineText.Substring(0, multiLineText.Length - 1);
}
#endregion
#region Internal Events
#endregion
#region Data
///
/// Whether the PropertyChanged event is fired
///
internal static Boolean _isPropertyChangedFired = false;
///
/// Whether this object is automatically generated while rendering.
/// And it is used while creating auto elements during render
///
internal Boolean _isAutoGenerated;
#endregion
}
}