Export to Excel in silverlight 5 - silverlight

I use the following code for export to excel,it works fine,but how can I change it to xport directly to .xlsx file not xml file,also I do not want to use automation because it works very slow.
Thanks.
public static class DataGridxtensions
{
public static void Export(this DataGrid dg)
{
ExportDataGrid(dg);
}
public static void ExportDataGrid(DataGrid dGrid)
{
SaveFileDialog objSFD = new SaveFileDialog() { DefaultExt = "xml", Filter = "Excel XML (*.xml)|*.xml", FilterIndex = 1 };
if (objSFD.ShowDialog() == true)
{
string strFormat = objSFD.SafeFileName.Substring(objSFD.SafeFileName.IndexOf('.') + 1).ToUpper();
StringBuilder strBuilder = new StringBuilder();
if (dGrid.ItemsSource == null) return;
List<string> lstFields = new List<string>();
if (dGrid.HeadersVisibility == DataGridHeadersVisibility.Column || dGrid.HeadersVisibility == DataGridHeadersVisibility.All)
{
foreach (DataGridColumn dgcol in dGrid.Columns)
lstFields.Add(FormatField(dgcol.Header.ToString(), strFormat, false));
BuildStringOfRow(strBuilder, lstFields, strFormat);
}
foreach (object data in dGrid.ItemsSource)
{
lstFields.Clear();
foreach (DataGridColumn col in dGrid.Columns)
{
string strValue = "";
Binding objBinding = null;
if (col is DataGridBoundColumn)
objBinding = (col as DataGridBoundColumn).Binding;
if (col is DataGridTemplateColumn)
{
//This is a template column... let us see the underlying dependency object
DependencyObject objDO = (col as DataGridTemplateColumn).CellTemplate.LoadContent();
FrameworkElement oFE = (FrameworkElement)objDO;
FieldInfo oFI = oFE.GetType().GetField("TextProperty");
if (oFI != null)
{
if (oFI.GetValue(null) != null)
{
if (oFE.GetBindingExpression((DependencyProperty)oFI.GetValue(null)) != null)
objBinding = oFE.GetBindingExpression((DependencyProperty)oFI.GetValue(null)).ParentBinding;
}
}
}
if (objBinding != null)
{
if (objBinding.Path.Path != "")
{
PropertyInfo pi = data.GetType().GetProperty(objBinding.Path.Path);
if (pi != null) strValue = pi.GetValue(data, null).ToString();
}
if (objBinding.Converter != null)
{
if (strValue != "")
strValue = objBinding.Converter.Convert(strValue, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();
else
strValue = objBinding.Converter.Convert(data, typeof(string), objBinding.ConverterParameter, objBinding.ConverterCulture).ToString();
}
}
lstFields.Add(FormatField(strValue, strFormat, true));
}
BuildStringOfRow(strBuilder, lstFields, strFormat);
}
StreamWriter sw = new StreamWriter(objSFD.OpenFile());
if (strFormat == "XML")
{
//Let us write the headers for the Excel XML
sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
sw.WriteLine("<?mso-application progid=\"Excel.Sheet\"?>");
sw.WriteLine("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\">");
sw.WriteLine("<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\">");
sw.WriteLine("<Author>Arasu Elango</Author>");
sw.WriteLine("<Created>" + DateTime.Now.ToLocalTime().ToLongDateString() + "</Created>");
sw.WriteLine("<LastSaved>" + DateTime.Now.ToLocalTime().ToLongDateString() + "</LastSaved>");
sw.WriteLine("<Company>Atom8 IT Solutions (P) Ltd.,</Company>");
sw.WriteLine("<Version>12.00</Version>");
sw.WriteLine("</DocumentProperties>");
sw.WriteLine("<Worksheet ss:Name=\"Export\" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\">");
sw.WriteLine("<Table>");
}
sw.Write(strBuilder.ToString());
if (strFormat == "XML")
{
sw.WriteLine("</Table>");
sw.WriteLine("</Worksheet>");
sw.WriteLine("</Workbook>");
}
sw.Close();
}
}
private static void BuildStringOfRow(StringBuilder strBuilder, List<string> lstFields, string strFormat)
{
switch (strFormat)
{
case "XML":
strBuilder.AppendLine("<Row>");
strBuilder.AppendLine(String.Join("\r\n", lstFields.ToArray()));
strBuilder.AppendLine("</Row>");
break;
case "CSV":
strBuilder.AppendLine(String.Join(",", lstFields.ToArray()));
break;
}
}
private static string FormatField(string data, string format, bool isNumber)
{
switch (format)
{
case "XML":
if (isNumber)
{
return String.Format("<Cell><Data ss:Type=\"Number\">{0}</Data></Cell>", data);
}
else
{
return String.Format("<Cell><Data ss:Type=\"String\">{0}</Data></Cell>", data);
}
case "CSV":
return String.Format("\"{0}\"", data.Replace("\"", "\"\"\"").Replace("\n", "").Replace("\r", ""));
}
return data;
}
}

I can think of two options.
First, there are several component vendors who have solved this problem. There's SyncFusion's XlsIo, and Infragistics, and Telerik (looks like they have .xls only).
If the financial cost is too high, then you might consider OpenXml. The learning curve would be a bit steeper, and you can't use it directly from Silverlight -- you'd have to make the server convert your data to an .xlsx file and then your client would save the results. Also, you'll need to be aware of this issue.
But, it is free. I have had some success reading Excel files with it. I think this might be the NuGet package you'd need, or you can download an installer.
Fortunately for me, my employer paid for the first option above when we needed to create an .xlsx file. :-)

Yup office Automation way to slow! I had to change to, I used code from
http://www.codeproject.com/Articles/45731/Export-Silverlight-DataGrid-to-Excel-XML-CSV?msg=4829021#xx4829021xx

Related

Save same changes to multiple databases with Entity Framework

I have 3 Oracle databases; production, test, development. For the most part, they are all identical. In my application, I would like the changes to be applied to multiple databases. For example:
using (var context = new Context())
{
context.People.Add(new Person { name = "sean" });
context.SaveChanges();
}
I then tried to override the SaveChanges method and save to multiple databases by doing this:
public void SaveChanges(int auditPersonNumber)
{
OracleCredentials.Default.Server = "VDev";
base.SaveChanges();
OracleCredentials.Default.Server = "VTest";
base.SaveChanges();
OracleCredentials.Default.Server = "VProd";
base.SaveChanges();
}
This didn't work but should explain what I am trying to achieve.
I haven't yet used EntityFramework against an Oracle database, but it should be similar to connecting against SQL Server in that the database name is specified via a ConnectionString. Your project should have a config file (web.config, app.config, or if it's a .NET Core application it could be in appsettings.json) with that ConnectionString in it.
For example:
<add name="YourConnectionString" providerName="YourOracleProviderName" connectionString="User Id=test;Password=testpassword;Data Source=eftest" />
The DbContext base constructor accepts a string argument that specifies which ConnectionString it should use, and thus which database to connect to. If you look into your context class, the default constructor should call the base constructor with that argument.
public YourDbContext() : base("YourConnectionString") {}
In order to save to multiple databases you will need to work against different instances of DbContext each with a different ConnectionString argument. So, your config will need to list a few different connection strings for every Db and you'll probably want your DbContext class to allow the argument in its constructor as well.
Perhaps the SaveChanges method implementation could instantiate the other DbContexts you'd need to use:
public void SaveChanges(int auditPersonNumber)
{
using (var context = new Context("OtherConnectionString1"))
{
// apply same changes
context.SaveChanges();
}
using (var context = new Context("OtherConnectionString2"))
{
// apply same changes
context.SaveChanges();
}
base.SaveChanges();
}
As for the applying the same changes, I would expect you can read them out from the DbContext ChangeTracker. There's an explanation about that using EF Core here but in earlier versions it's similar: http://www.entityframeworktutorial.net/efcore/changetracker-in-ef-core.aspx
Also keep in mind that the SaveChanges call to OtherConnectionString1 could succeed while others could fail, so the data might be inconsistent in your different databases. You may have to look into using transactions across multiple databases but I haven't done this yet myself.
I was able to figure out a solution thanks to the help of Sangman.
public class Context : Shared.Data.Context
{
new public void SaveChanges(int auditPersonNumber)
{
var errors = string.Empty;
var testConnectionString = "ConnectionString";
var developmentConnectionString = "ConnectionString";
//Save to test database
if (SecurityMaintenanceUser.ApplyToTest)
errors = ApplyToDatabase(testConnectionString, auditPersonNumber, "Test");
if (!string.IsNullOrWhiteSpace(errors))
errors += "\n\n";
//Save to development database
if (SecurityMaintenanceUser.ApplyToDevelopment)
errors += ApplyToDatabase(developmentConnectionString, auditPersonNumber, "Development");
if (!string.IsNullOrWhiteSpace(errors))
MessageBox.Show(errors, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
//Save to production database
base.SaveChanges(auditPersonNumber);
}
private string ApplyToDatabase(string connectionString, int auditPersonNumber, string server)
{
try
{
using (var context = new Context(connectionString))
{
context.Configuration.ValidateOnSaveEnabled = false;
foreach (var entry in ChangeTracker.Entries())
{
var dataSet = context.Set(entry.Entity.GetType());
if (entry.State == EntityState.Added)
{
dataSet.Add(entry.Entity);
}
else if (entry.State == EntityState.Deleted)
{
var contextEntity = dataSet.Find(GetPrimaryKeyValues(entry));
context.DeleteEntity(contextEntity, auditPersonNumber);
}
else if (entry.State == EntityState.Modified)
{
var contextEntity = dataSet.Find(GetPrimaryKeyValues(entry));
context.Entry(CopyProperties(entry.Entity, contextEntity)).State = EntityState.Modified;
}
}
context.SaveChanges(auditPersonNumber);
return string.Empty;
}
}
catch (Exception e)
{
return $"Failed to apply database changes to {server}.\n{e.GetFullMessage()}";
}
}
private object CopyProperties(object source, object destination)
{
if (source == null || destination == null)
throw new Exception("Source or/and Destination Objects are null");
var typeDest = destination.GetType();
var typeSrc = source.GetType();
foreach (var srcProp in typeSrc.GetProperties())
{
if (srcProp.Name == "Type" || srcProp.Name == "AuthenticationLog")
continue;
//This blocks any complex objects attached to the entity, will need to be changed for your application
if (srcProp.PropertyType.FullName.Contains("Library.Shared"))
continue;
if (!srcProp.CanRead)
continue;
var targetProperty = typeDest.GetProperty(srcProp.Name);
if (targetProperty == null)
continue;
if (!targetProperty.CanWrite)
continue;
if (targetProperty.GetSetMethod(true)?.IsPrivate == true)
continue;
if ((targetProperty.GetSetMethod().Attributes & MethodAttributes.Static) != 0)
continue;
if (!targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType))
continue;
targetProperty.SetValue(destination, srcProp.GetValue(source, null), null);
}
return destination;
}
private object GetPrimaryKeyValues(DbEntityEntry entry)
{
var objectStateEntry = ((IObjectContextAdapter)this).ObjectContext.ObjectStateManager.GetObjectStateEntry(entry.Entity);
return objectStateEntry.EntityKey.EntityKeyValues[0].Value;
}
public static string GetFullMessage(this Exception ex)
{
return ex.InnerException == null ? ex.Message : $"{ex.Message}\n{ex.InnerException.GetFullMessage()}";
}
public static string Replace(this string source, string oldString, string newString, StringComparison comp)
{
int index = source.IndexOf(oldString, comp);
if (index >= 0)
{
source = source.Remove(index, oldString.Length);
source = source.Insert(index, newString);
}
if (source.IndexOf(oldString, comp) != -1)
source = Replace(source, oldString, newString, comp);
return source;
}
}

Enum switch in Java

I have this Java class where I am writing the code for applying the overrides. I want to know if using ENUM is appropriate or if I need to use the switch case, how can I use it? Also, I have the for loop that I need to use as a common block of code for each override type. Apart from that, I do have few separate fields that I need to code for each override type.
public class EWFMService
{
private WorkbrainSystemAccessService wsa = new WorkbrainSystemAccessService();
private static final org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(EWFMService.class);
private final static String ovrCalcGrp = "ovrCalcGrp";
private DBConnection conn = null;
private int empId;
private Date ovrDate;
private String ovrTime;
private String ovrAction;
public List<EWFMServiceData> getProcessEWFMOverrides(String userName, String password, List<EWFMServiceInputData> inputData)
throws WSApplicationException{
logger.debug("EWFM Service");
wsa.logOn(userName, password);
List<EWFMServiceData> returnList = new ArrayList<EWFMServiceData> ();
logger.debug("userName = " + userName);
DBConnection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
conn = new DBConnection(ConnectionManager.getConnection());
for (int i = 0; i < inputData.size(); i++)
{
Here I want to retrieve the emp_id from the database, store the value in a variable and be able to use the variable in the rest of my program. How do I do it? To retrieve the emp_id, I am using the following query.
conn = new DBConnection(ConnectionManager.getConnection());
String sql = "SELECT EMP_ID FROM EMPLOYEE_HISTORY"
+ " WHERE EMP_VAL2 = **This is where I want to use the variable in which the values of emp_id will be stored. There can be more than 100 emp_ids**"
+ " AND SYSDATE BETWEEN EMPHIST_START_DATE AND EMPHIST_END_DATE";
EWFMServiceInputData inData = (EWFMServiceInputData) inputData.get(i);
OverrideType ot = OverrideType.getOverrideType(inData.getRecordType());
logger.debug("override type = " + ot.toString());
logger.debug("inputData ["+i+"] = " + inData.toString());
OverrideAccess oa = new OverrideAccess(conn);
OverrideData ovr = new OverrideData();
ovr.setOvrUdf4(inData.getReferenceId().toString());
if (ovrAction.equals("APPLY")) {
ovr.setOvrStatus(OverrideData.PENDING);
Here I want to determine the Action. If it is Apply, then I need to find out the recordType. So basically branch it out for each recordType using if else statements or enum as I believe switch doesn't support Java 1.5 which is what I am using. Then for each recordType, I branch out and write the appropriate code corresponding to that recordType. If Action is CANCEL, then I just write the following code.
} else if (ovrAction.equals("CANCEL")) {
String sql = "SELECT * FROM OVERRIDE"
+ " WHERE OVR_UDF4 = ?"
+ " AND OVRTYP_ID = ?";
ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()); {
ovr.assignByName(rs);
ovr.setUpdated(false);
ovr.setRetrieved(true);
ovr.setOvrStatus(OverrideData.CANCEL);
oa.save(ovr);
}
}
ovr.setEmpId(empId);
String strOvrDate = inData.getOvrStartDate();
ovr.setOvrStartDate(DateHelper.parseDate(strOvrDate, "MM/dd/yyyy"));
if (ovrStartTime != null) {
ovr.setOvrStartTime(ovrTime);
}
Object ovrEndDate;
if (ovrEndDate != null) {
ovr.setOvrEndDate(ovrDate);
}
Object ovrEndTime;
if (ovrEndTime!= null) {
ovr.setOvrEndTime(ovrTime);
}
ovr.setOvrComment(inData.getOvrComments());
ovr.setWbuName(inData.getWbuName());
ovr.setWbuNameActual(inData.getWbuNameActual());
ovr.setOvrNewValue("VAC");
ovr.setOvrCreateDate(new Date());
ovr.setOvrtypId(103);
oa.insert(ovr);
RuleEngine.runCalcGroup(conn,
empId,
ovrDate,
ovrDate);
//COMMON BLOCK ENDS HERE
EWFMServiceData outData = new EWFMServiceData();
outData.setReferenceId(inData.getReferenceId());
String [] status = {"SUCCESS", "ERROR", "LOCKED", "EXCEPTION"};
Random ran = new Random();
String gen = status[ran.nextInt(status.length)];
logger.debug("Status is" + status );
outData.setStatus(gen);
if (gen.equals("SUCCESS")){
outData.setErrorDetails("");
} else if (gen.equals("ERROR")) {
outData.setErrorDetails("Usage of time code VAC is not allowed; balance is insufficient." + " error");
} else if (gen.equals("LOCKED")) {
outData.setErrorDetails("Timesheet cannot be edited because it is locked for payroll close." + "locked");
} else if (gen.equals("EXCEPTION")) {
outData.setErrorDetails("{ML}QR_INCORRECT_CONDITION_PARAMETER{/ML}Error in condition AWA Is Self Override Condition: java.lang.NullPointerException{ARGS}AWA Is Self Override Conditionjava.lang.NullPointerException{/ARGS" + "exception");
}
returnList.add(outData);
}
}catch (Exception e){
logger.error("Error occured",e);
throw new WSApplicationException("Error retrieved",e);
}finally{
SQLUtil.cleanUp(conn, ps, rs);
}
wsa.logOff();
logger.debug("inputData+ ");
return returnList;
}
// I need to know if writing enum is okay or can I just write a switch case above in the for loop and branch each override type and declare their individual variables there? What's the best way? Can someone help me with the code?
public enum OverrideType {
WORKDETAIL,
WORKPREMIUM,
EMPLOYEESCHEDULE,
EMPLOYEE;
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
if(recordType.equals("Work Detail")) {
return WORKDETAIL;
} else if (recordType.equals("Work Premium")) {
return WORKPREMIUM;
} else if (recordType.equals("Schedule")) {
return EMPLOYEESCHEDULE;
} else if (recordType.equals("Shift Pattern")) {
return EMPLOYEE;
} else {
throw new IllegalArgumentException("Record Type cannot be" + recordType);
}
}
}
}
THE OTHER FIELDS I NEED TO INCLUDE ARE AS FOLLOWS:
FOR WORKDETAIL, I NEED TO USE TIMECODE OF FORMAT THAT IS SENT BY THE CLIENT.
FOR WORK PREMIUM, I NEED TO USE TIMECODE OF FORMAT THAT IS SENT BY THE CLIENT AND ANOTHER FIELD IS MINUTES THAT GIVES THE NUMBER OF MINUTES WHICH IS ALSO SENT BY THE CLIENT.
Generally, using enums is appropriate, especially if you have a defined set of possible types.
You can also add behavior to the enums, which could make your enum a little bit more sophisticated:
public enum OverrideType {
WORKDETAIL("Work Detail"),
WORKPREMIUM("Work Premium"),
EMPLOYEESCHEDULE("Schedule"),
EMPLOYEE("Shift Pattern");
private String identifier;
private OverrideType(String identifier){
this.identifier = identifier;
}
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
for (OverrideType ot : OverrideType.values()) {
if (recordType.equals(ot.identifier)) {
return ot;
}
}
return null;
}
}
The following example shows how to use an interface in enums or an abstract method definition:
public enum OverrideType implements OverrideTypeIF {
WORKDETAIL("Work Detail") {
public int getKey() {
return 0;
}
},
WORKPREMIUM("Work Premium") {
public int getKey() {
return 0;
}
},
EMPLOYEESCHEDULE("Schedule") {
public int getKey() {
return 0;
}
},
EMPLOYEE("Shift Pattern") {
public int getKey() {
return 0;
}
public void myInterfaceMethod() {
// do type specific behavior
}
};
private String identifier;
private OverrideType(String identifier){
this.identifier = identifier;
}
public abstract int getKey();
public void myInterfaceMethod() {
// do default behavior
}
public static OverrideType getOverrideType(String recordType) {
if(recordType == null) {
throw new IllegalArgumentException("Record Type cannot be null");
}
for (OverrideType ot : OverrideType.values()) {
if (recordType.equals(ot.identifier)) {
return ot;
}
}
return null;
}
}
public interface OverrideTypeIF {
void myInterfaceMethod();
}

Query CRM data in Silverlight

I am building a silverlight app for CRM 2011 and I was wondering what the best way to retrieve data from the CRM system is.
I have linked in my organisation as a service reference and am able to access that. I have seen a few different ways to retrieve data but they all seem rather complicated. Is there anything like what we can use in plugins such as a fetch XMl query or a simple Service.Retrieve method?
Thanks
If you add a service reference to your project you can use LINQ to query the datasets.
You can download the CSDL from Developer Resources under the customisation area.
private FelineSoftContext context;
private System.String serverUrl;
private DataServiceCollection<SalesOrder> _orders;
public MainPage()
{
InitializeComponent();
serverUrl = (String)GetContext().Invoke("getServerUrl");
//Remove the trailing forward slash returned by CRM Online
//So that it is always consistent with CRM On Premises
if (serverUrl.EndsWith("/"))
serverUrl = serverUrl.Substring(0, serverUrl.Length - 1);
Uri ODataUri = new Uri(serverUrl + "/xrmservices/2011/organizationdata.svc/", UriKind.Absolute);
context = new FelineSoftContext(ODataUri) { IgnoreMissingProperties = true };
var orders = from ord in context.SalesOrderSet
orderby ord.Name
select new SalesOrder
{
Name = ord.Name,
SalesOrderId = ord.SalesOrderId
};
_orders = new DataServiceCollection<SalesOrder>();
_orders.LoadCompleted += _orders_LoadCompleted;
_orders.LoadAsync(orders);
}
void _orders_LoadCompleted(object sender, LoadCompletedEventArgs e)
{
if (e.Error == null)
{
if (_orders.Continuation != null)
{
_orders.LoadNextPartialSetAsync();
}
else
{
OrderLookup.ItemsSource = _orders;
OrderLookup.DisplayMemberPath = "Name";
OrderLookup.SelectedValuePath = "Id";
}
}
}
You will also need to add a method in your class as below:
private static ScriptObject GetContext()
{
ScriptObject xrmProperty = (ScriptObject)HtmlPage.Window.GetProperty("Xrm");
if (null == xrmProperty)
{
//It may be that the global context should be used
try
{
ScriptObject globalContext = (ScriptObject)HtmlPage.Window.Invoke("GetGlobalContext");
return globalContext;
}
catch (System.InvalidOperationException)
{
throw new InvalidOperationException("Property \"Xrm\" is null and the Global Context is not available.");
}
}
ScriptObject pageProperty = (ScriptObject)xrmProperty.GetProperty("Page");
if (null == pageProperty)
{
throw new InvalidOperationException("Property \"Xrm.Page\" is null");
}
ScriptObject contextProperty = (ScriptObject)pageProperty.GetProperty("context");
if (null == contextProperty)
{
throw new InvalidOperationException("Property \"Xrm.Page.context\" is null");
}
return contextProperty;
}
You will need to add an additional class library and put the following code within it. Change the class name to match the Context you exported:
partial class FelineSoftContext
{
#region Methods
partial void OnContextCreated()
{
this.ReadingEntity += this.OnReadingEntity;
this.WritingEntity += this.OnWritingEntity;
}
#endregion
#region Event Handlers
private void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
{
ODataEntity entity = e.Entity as ODataEntity;
if (null == entity)
{
return;
}
entity.ClearChangedProperties();
}
private void OnWritingEntity(object sender, ReadingWritingEntityEventArgs e)
{
ODataEntity entity = e.Entity as ODataEntity;
if (null == entity)
{
return;
}
entity.RemoveUnchangedProperties(e.Data);
entity.ClearChangedProperties();
}
#endregion
}
public abstract class ODataEntity
{
private readonly Collection<string> ChangedProperties = new Collection<string>();
public ODataEntity()
{
EventInfo info = this.GetType().GetEvent("PropertyChanged");
if (null != info)
{
PropertyChangedEventHandler method = new PropertyChangedEventHandler(this.OnEntityPropertyChanged);
//Ensure that the method is not attached and reattach it
info.RemoveEventHandler(this, method);
info.AddEventHandler(this, method);
}
}
#region Methods
public void ClearChangedProperties()
{
this.ChangedProperties.Clear();
}
internal void RemoveUnchangedProperties(XElement element)
{
const string AtomNamespace = "http://www.w3.org/2005/Atom";
const string DataServicesNamespace = "http://schemas.microsoft.com/ado/2007/08/dataservices";
const string DataServicesMetadataNamespace = DataServicesNamespace + "/metadata";
if (null == element)
{
throw new ArgumentNullException("element");
}
List<XElement> properties = (from c in element.Elements(XName.Get("content", AtomNamespace)
).Elements(XName.Get("properties", DataServicesMetadataNamespace)).Elements()
select c).ToList();
foreach (XElement property in properties)
{
if (!this.ChangedProperties.Contains(property.Name.LocalName))
{
property.Remove();
}
}
}
private void OnEntityPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (!this.ChangedProperties.Contains(e.PropertyName))
{
this.ChangedProperties.Add(e.PropertyName);
}
}
#endregion
}
I am will suggest you to use Silvercrmsoap , it's very easy to use. I have used this in my silverlight projects.

Convert BeginInvoke Code From Winforms To Wpf

I have found out that ISynchronizeInvoke cannot be used in WPF after having tried to convert the following code unsuccessfully. Can anybody help?
private static void EVENT_R(Delegate #event, object[] data)
{
if (#event != null)
{
foreach (var A_C in #event.GetInvocationList())
{
var NewTp = (ISynchronizeInvoke)A_C.Target;
if (NewTp != null && NewTp.InvokeRequired)
{
NewTp.BeginInvoke(A_C, data);
}
else
{
A_C.DynamicInvoke(data);
}
}
}
}
If NewTp is a UIElement, then you need to cast to UIElement and call UIElement.Dispatcher.BeginInvoke:
var NewTp = (UIElement)A_C.Target;
if (NewTp != null)
{
NewTp.Dispatcher.BeginInvoke(A_C, data);
}

How to log name/path of clicked control in WPF?

I use the following code to log every click in our WinForms application. In essence it looks up a control from its HWND and then prints the types and names of the control and all of its parents. Something like MainForm"myWindow">TabPanel"mainTab">Button"save"
internal class ClickLogger : IMessageFilter
{
private const int WM_LBUTTONDOWN = 0x0201;
private const int WM_LBUTTONDBLCLK = 0x0203;
private const int WM_RBUTTONDOWN = 0x0204;
private const int MaxRecurseDepth = 30;
private readonly ILogger _log;
public ClickLogger(ILogger logger)
{
_log = logger;
}
[DebuggerStepThrough]
public bool PreFilterMessage(ref Message message)
{
if (message.Msg == WM_LBUTTONDOWN
|| message.Msg == WM_RBUTTONDOWN
|| message.Msg == WM_LBUTTONDBLCLK)
{
string path = "Unknown";
Control ctl = Control.FromHandle(message.HWnd);
if (ctl != null)
{
path = PathFromControl(ctl, MaxRecurseDepth).ToString();
}
string logEntry = string.Format("{0} Click on {1}",
WndMsgToClickName(message.Msg), path);
if (_log.IsInfoEnabled)
{
_log.Info(logEntry);
}
}
return false;
}
private StringBuilder PathFromControl(Control control, int maxDepth)
{
if(maxDepth == 0)
{
_log.Warn("Max recursion {0} reached whilst resolving path of control", MaxRecurseDepth);
return new StringBuilder("ERR");
}
string name = control.GetType().Name;
if (control.Name.IsNotBlank())
{
name = name + "\"" + control.Name + "\"";
}
if (control.Parent != null && control.Parent != control)
{
return PathFromControl(control.Parent, maxDepth - 1).Append(">").Append(name);
}
return new StringBuilder(name);
}
public void Initialize()
{
Application.AddMessageFilter(this);
}
private static string WndMsgToClickName(int msgId)
{
switch (msgId)
{
case WM_LBUTTONDOWN:
return "Left";
case WM_LBUTTONDBLCLK:
return "Double";
case WM_RBUTTONDOWN:
return "Right";
default:
return "0x" + Convert.ToString(msgId, 16);
}
}
}
Recently we've started to mix WPF and WinForms and the above click logger simply prints "Unknown" for any click on a WPF control.
Is there a way I can perform a similar trick for WPF controls? A method that would work across technologies would be great.
well, it doesn't exactly work across technologies but for wpf you can use a combination of this to get the clicks and any of the helpers in this question to cycle through the parents to get the path.

Resources