How to change a ClassificationFormatDefinition - c#

My Visual Studio extension (VSIX) is derived from the Ook Language Example (found here). Basically, I have the following ClassificationFormatDefinition with a function loadSavedColor that loads the color the user has configured. Everything works fine.
[Name("some_unique_name")]
internal sealed class OokE : ClassificationFormatDefinition
{
public OokE()
{
DisplayName = "ook!"; //human readable version of the name
ForegroundColor = loadSavedColor();
}
}
Question: After the user has configured a new color, I like to invalidate the existing instance of class OokE or change the existing instances and set ForegroundColor. But whatever I do the syntax color is not updated.
I've tried:
Get a reference to class OokE and update ForegroundColor.
Invalidate the corresponding ClassificationTypeDefinition:
[Export(typeof(ClassificationTypeDefinition))]
[Name("ook!")]
internal static ClassificationTypeDefinition ookExclamation = null;

After hours of sifting through code I could create something that works. The following method UpdateFont called with colorKeyName equal to "some_unique_name" does the trick. I hope it is useful for someone.
private void UpdateFont(string colorKeyName, Color c)
{
var guid2 = Guid.Parse("{A27B4E24-A735-4d1d-B8E7-9716E1E3D8E0}");
var flags = __FCSTORAGEFLAGS.FCSF_LOADDEFAULTS | __FCSTORAGEFLAGS.FCSF_PROPAGATECHANGES;
var store = GetService(typeof(SVsFontAndColorStorage)) as IVsFontAndColorStorage;
if (store.OpenCategory(ref guid2, (uint)flags) != VSConstants.S_OK) return;
store.SetItem(colorKeyName, new[]{ new ColorableItemInfo
{
bForegroundValid = 1,
crForeground = (uint)ColorTranslator.ToWin32(c)
}});
store.CloseCategory();
}
After setting the new color, you will need to clear the cache with the following code:
IVsFontAndColorCacheManager cacheManager = this.GetService(typeof(SVsFontAndColorCacheManager)) as IVsFontAndColorCacheManager;
cacheManager.ClearAllCaches();
var guid = new Guid("00000000-0000-0000-0000-000000000000");
cacheManager.RefreshCache(ref guid);
guid = new Guid("{A27B4E24-A735-4d1d-B8E7-9716E1E3D8E0}"); // Text editor category

Related

How to get previous data in Xamarin.Forms

I am working on an application which is going to show updated dollar and euro rates for Turkey. I want to print green and red arrows depending on if rates went up or down since the last time user opened the app. So my question is how can I get previous data and how can I compare them with the current data?
CODE-BEHIND;
namespace Subasi.A.M.D
{
public partial class MainPage : ContentPage
{
float banknoteSellingUSD = 0;
float banknoteBuyingUSD = 0;
public MainPage()
{
InitializeComponent();
if (Device.OS == TargetPlatform.iOS)
Padding = new Thickness(10, 50, 0, 0);
else if (Device.OS == TargetPlatform.Android)
Padding = new Thickness(10, 20, 0, 0);
else if (Device.OS == TargetPlatform.WinPhone)
Padding = new Thickness(30, 20, 0, 0);
}
private void Button_Clicked(object sender, EventArgs e)
{
XmlDocument doc1 = new XmlDocument();
doc1.Load("http://www.tcmb.gov.tr/kurlar/today.xml");
XmlElement root = doc1.DocumentElement;
XmlNodeList nodes = root.SelectNodes("Currency");
foreach (XmlNode node in nodes)
{
var attributeKod = node.Attributes["Kod"].Value;
if (attributeKod.Equals("USD"))
{
var GETbanknoteSellingUSD = node.SelectNodes("BanknoteSelling")[0].InnerText;
var GETbanknoteBuyingUSD = node.SelectNodes("BanknoteBuying")[0].InnerText;
//if (banknoteSellingUSD > float.Parse(GETbanknoteSellingUSD)) isusdup = false;
//else isusdup = true;
banknoteSellingUSD = float.Parse(GETbanknoteSellingUSD);
banknoteBuyingUSD = float.Parse(GETbanknoteBuyingUSD);
labelUSDBuying.Text = banknoteSellingUSD.ToString("0.00");
labelUSDSelling.Text = banknoteBuyingUSD.ToString("0.00");
}
var attributeKod1 = node.Attributes["Kod"].Value;
if (attributeKod1.Equals("EUR"))
{
var GETbanknoteSellingEU = node.SelectNodes("BanknoteSelling")[0].InnerText;
var GETbanknoteBuyingEU = node.SelectNodes("BanknoteBuying")[0].InnerText;
var banknoteSellingEU = float.Parse(GETbanknoteSellingEU);
var banknoteBuyingEU = float.Parse(GETbanknoteBuyingEU);
labelEUSelling.Text = banknoteSellingEU.ToString("0.00");
labelEUBuying.Text = banknoteBuyingEU.ToString("0.00");
}
}
}
}
}
print green and red arrows depending on if rates went up or down since the last time user opened the app
To achieve this, you will have to store the previous value. The easiest way may be to use the properties dictionary (see here). You can store simple properties within that.
You could capsule the behavior in a class
public class ExchangeCourseSource : IExchangeCourseSource
{
public ExchangeCourseSource(XmlDocument sourceDocument)
{
this.sourceDocument = sourceDocument;
}
public ExchangeCourse GetCourse(string currency)
{
// parse from XML (see your code)
}
}
class ExchangeCourse
{
public string Currency { get; set; }
public double ExchangeRate { get; set; }
public double Difference { get; set; }
}
and decorate this with a class that stores and retrieved the courses to and fro the properties dictionary
public class StoredExchangeCourseSourceDecorator : IExchangeCourseSource
{
public ExchangeCourseSource(IExchangeCourceSource source, Application application)
{
this.source = source;
this.application = application;
}
public ExchangeCourse GetCourse(string currency)
{
var exchangeCourse = source.GetCourse(currency);
if(HasStoredCourse())
{
var storedCourse = GetStoredCourse(currency);
exchangeCourse.Difference = exchangeCourse.ExchangeRate - storedCourse;
}
StoreCourse(exchangeCourse);
return exchangeCourse;
}
private bool HasStoredCourse(string currency)
{
return application.Properties.ContainsKey(currency);
}
private double GetStoredCourse(string currency)
{
return (double)application.Properties[currency];
}
private void StoreCourse(ExchangeCourse exchangeCourse)
{
application.Properties[exchangeCourse.Currency] = exchangeCourse.ExchangeRate;
application.SavePropertiesAsync().Wait();
}
}
OK, so to answer the question, You have to store data somewhere, the easiest method will be in ISharedPreferences to save and restore data.
From AndroidDeveloper :
If you don't need to store a lot of data and it doesn't require
structure, you should use SharedPreferences. The SharedPreferences
APIs allow you to read and write persistent key-value pairs of
primitive data types: booleans, floats, ints, longs, and strings.
The key-value pairs are written to XML files that persist across user
sessions, even if your app is killed. You can manually specify a name
for the file or use per-activity files to save your data.
So it's a good place to store some info and retrieve them.
All you have to do is to get an instance from ISharedPreferences and use ISharedPreferencesEditor to insert and retrieve data.
You find it in Android.Content Namespace
To save your data you can apply this code :
ISharedPreferences preference = PreferenceManager.GetDefaultSharedPreferences(this);
ISharedPreferencesEditor editor = preference.Edit();
editor.PutString("key", "Value");
editor.Apply();
In your case, you can PutFloat
So your data which is "Value" is saved with a key named "key" is now saved
then you can retrieve data by :
ISharedPreferences preference = PreferenceManager.GetDefaultSharedPreferences(this);
var a = preference .GetString("key", "null");//"null" is the default value if the value not found. and the key, it to retrieve a specific data as we stored the data with the key named "key"
In your case, use GetFloat
So you get your value stored in a variable a.
All you have to do is : Store your data in the Sharedpreference when a new data changed or OnSleep() method which will be called when the app closed, then in OnCreate() method in your app, call the data saved in the SharedPreference and compare it with the new data.

How to set PageOptions in TuesPechkin

I'm using TuesPechkin (the C# wrapper of wkhtmltopdf) and have it generating PDF files from HTML.
However, I would like to set the --disable-smart-shrinking option, which is listed in the wkhtmltopdf documentation as a PageOption
How can I do that?
public sealed class PdfConverter
{
static readonly PdfConverter instance = new PdfConverter();
private IConverter converter;
static PdfConverter()
{
}
PdfConverter()
{
// Keep the converter somewhere static, or as a singleton instance! Do NOT run this code more than once in the application lifecycle!
this.converter = new ThreadSafeConverter( new RemotingToolset<PdfToolset>( new Win32EmbeddedDeployment( new TempFolderDeployment())));
}
public static PdfConverter Instance
{
get { return instance; }
}
public byte[] ConvertHtmlToPdf(string html)
{
var document = new HtmlToPdfDocument
{
Objects = { new ObjectSettings { HtmlText = html } }
// Where are PageOptions? Thats where --disable-smart-shrinking is
};
return converter.Convert(document);
}
}
The --disable-smart-shrinking option does not exist in the API -- well, it kind of does, but in the form of it's opposite sibling: --enable-smart-shrinking.
That property is available in the TuesPechkin API as WebSettings.EnableIntelligentShrinking as seen in the TuesPechkin source code. It was named that way in TuesPechkin because that is how it is named in wkhtmltopdf's API as seen in the wkhtmltopdf source code.
You can also see there that the default value is true (from wkhtmltopdf), so if you set WebSettings.EnableIntelligentShrinking to false you should get the result you're aiming for.
It seems this functionality hasn't been implemented in Tuespechkin. I can't find it here, where most of the page options are located.
I guess he forgot to implement the option, so probably best to request the feature here. Or you can also add the feature yourself. :)

RavenDB throws a JSON deserialisation error when retrieving document

I've just completed a round of refactoring of my application, which has resulted in my removing a project that was no longer required and moving its classes into a different project. A side effect of this is that my User class, which is stored in RavenDB, has a collection property of a type moved to the new assembly. As soon as I attempt to query the session for the User class I get a Json deserialisation error. The issue is touched upon here but the answers don't address my issue. Here's the offending property:
{
"OAuthAccounts": {
"$type": "System.Collections.ObjectModel.Collection`1[
[Friendorsement.Contracts.Membership.IOAuthAccount,
Friendorsement.Contracts]], mscorlib",
"$values": []
},
}
OAuthAccounts is a collection property of User that used to map here:
System.Collections.ObjectModel.Collection`1[[Friendorsement.Contracts.Membership.IOAuthAccount, Friendorsement.Contracts]]
It now maps here:
System.Collections.ObjectModel.Collection`1[[Friendorsement.Domain.Membership.IOAuthAccount, Friendorsement.Domain]]
Friendorsement.Contracts no longer exists. All of its types are now in Friendorsement.Domain
I've tried using store.DatabaseCommands.StartsWith("User", "", 0, 128) but that didn't return anything.
I've tried looking at UpdateByIndex but not got very far with it:
store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new[]
{
new PatchRequest { // unsure what to set here }
});
I'm using Raven 2.0
Below is a simple sample application that shows you the patching Metadata. While your example is a little different this should be a good starting point
namespace SO19941925
{
internal class Program
{
private static void Main(string[] args)
{
IDocumentStore store = new DocumentStore
{
Url = "http://localhost:8080",
DefaultDatabase = "SO19941925"
}.Initialize();
using (IDocumentSession session = store.OpenSession())
{
for (int i = 0; i < 10; i++)
{
session.Store(new User {Name = "User" + i});
}
session.SaveChanges();
}
using (IDocumentSession session = store.OpenSession())
{
List<User> users = session.Query<User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).ToList();
Console.WriteLine("{0} SO19941925.Users", users.Count);
}
Operation s = store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new ScriptedPatchRequest
{
Script = #"this['#metadata']['Raven-Clr-Type'] = 'SO19941925.Models.User, SO19941925';"
}, true
);
s.WaitForCompletion();
using (IDocumentSession session = store.OpenSession())
{
List<Models.User> users =
session.Query<Models.User>().Customize(x => x.WaitForNonStaleResultsAsOfNow()).ToList();
Console.WriteLine("{0} SO19941925.Models.Users", users.Count);
}
Console.ReadLine();
}
}
internal class User
{
public string Name { get; set; }
}
}
namespace SO19941925.Models
{
internal class User
{
public string Name { get; set; }
}
}
UPDATE: Based on the initial answer above, here is the code that actually solves the OP question:
store.DatabaseCommands.UpdateByIndex("Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Users"},
new ScriptedPatchRequest
{
Script = #"this['OAuthAccounts']['$type'] =
'System.Collections.ObjectModel.Collection`1[
[Friendorsement.Domain.Membership.IFlexOAuthAccount,
Friendorsement.Domain]], mscorlib';",
}, true
);
Here are two possible solutions:
Option 1: Depending on what state your project is in, for example if you are still in development, you could easily just delete that collection out of RavenDB from the Raven Studio and recreate all those User documents. All the new User documents should then have the correct class name and assembly and should then deserialize correctly. Obviously, if you are already in production, this probably won't be a good option.
Option 2: Depending on how many User documents you have, you should be able to manually edit each one to specify the correct C# class name and assembly, so that they will be deserialized correctly. Again, if you have too many objects to manually modify, this may not be a good option; however, if there are just a few, it shouldn't be too bad to open each one up go to the metadata tab and paste the correct value for "Raven-Entity-Name" and "Raven-Clr-Type".
I ended up doing this:
Advanced.DatabaseCommands.UpdateByIndex(
"Raven/DocumentsByEntityName",
new IndexQuery {Query = "Tag:Album"},
new []{ new PatchRequest() {
Type = PatchCommandType.Modify,
Name = "#metadata",
Nested= new []{
new PatchRequest{
Name= "Raven-Clr-Type",
Type = PatchCommandType.Set,
Value = "Core.Model.Album, Core" }}}},
false);

Problem Creating Instances of ASP.NET User Controls Programmatically

I am able to create controls pro grammatically using the code below without issue:
FileListReader fReader = (FileListReader)LoadControl("~/Controls/FileListReader.ascx");
phFileLists.Controls.Add(fReader);
However, I would like to change the control so that I can give it a constructor like this:
public FileListReader(Int32 itemGroupId, Int32 documentType, String HeaderString, String FooterString, bool isAdminUser)
{
base.Construct();
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}
and then I should be able to call the control like this:
FileListReader fReader = (FileListReader)LoadControl(typeof(FileListReader), new Object[] { itemGroupId, 6, "Sell Sheets", "<br /><br />", isAdminUser });
However, when I do this I always get an error that my in page controls within my FileListReader Control have not been instantiated and I get a null reference error. So for example I have an <asp:Label></asp:label> control that errors out when I try to set it's text on the Page_Load method. What is causing this? I figured the base.Construct() would have solved this issue but it obviously has not.
The proper way to inherit a constructor is like this:
class FileListReader : WebControl
{
public FileListReader(Int32 itemGroupId,
Int32 documentType,
String HeaderString,
String FooterString,
bool isAdminUser) : base() // <-- notice the inherit
{
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}
// ... other code here ... //
}
Does changing your constructor like that fix the issue?
I am not sure that calling base.Contruct() is what you should be doing, try calling the default contructor of the base class example below:
public FileListReader(Int32 itemGroupId, Int32 documentType, String HeaderString, String FooterString, bool isAdminUser) :base()
{
base.Construct();
this.itemGroupId = itemGroupId;
this.documentType = documentType;
this.HeaderString = HeaderString;
this.FooterString = FooterString;
this.isAdminUser = isAdminUser;
}

How To add another constructor with parameter in linq class(Table)

I am using LINQ to SQL in an ASP.NET project. While inserting the table I need to convert the values to the particular table object and I need to insert.
For that I created a new constructor in that table with parameter so that I can assign my value to that table object , the assign the functionality is working but while inserting (obj.TS_Questions.InsertOnSubmit(mytableobject);) I get null exception.
my code::
default constructor for my table
public TS_Question()
{
this._TS_Options = new EntitySet<TS_Option>(new Action<TS_Option>(this.attach_TS_Options), new Action<TS_Option>(this.detach_TS_Options));
this._TS_QuestGroups = new EntitySet<TS_QuestGroup>(new Action<TS_QuestGroup>(this.attach_TS_QuestGroups), new Action<TS_QuestGroup>(this.detach_TS_QuestGroups));
this._TS_QuestRecords = new EntitySet<TS_QuestRecord>(new Action<TS_QuestRecord>(this.attach_TS_QuestRecords), new Action<TS_QuestRecord>(this.detach_TS_QuestRecords));
this._TS_Admin = default(EntityRef<TS_Admin>);
this._TS_LevelType = default(EntityRef<TS_LevelType>);
this._TS_OptionTypeLT = default(EntityRef<TS_OptionTypeLT>);
OnCreated();
}
constructor created by me
public TS_Question(Guid Quest_QuestIDBL, string Quest_NameBL, Nullable<Guid> Quest_OptionTypeIDBL, Guid Quest_AdminIDBL, Guid Ques_LevelIDBL, int Quest_TimeBL, int Quest_MarkBL, string Qest_ExplanationBL, Nullable<bool> Qest_IsMultipleAnswerBL)
{
this._TS_Options = new EntitySet<TS_Option>(new Action<TS_Option>(this.attach_TS_Options), new Action<TS_Option>(this.detach_TS_Options));
this._TS_QuestGroups = new EntitySet<TS_QuestGroup>(new Action<TS_QuestGroup>(this.attach_TS_QuestGroups), new Action<TS_QuestGroup>(this.detach_TS_QuestGroups));
this._TS_QuestRecords = new EntitySet<TS_QuestRecord>(new Action<TS_QuestRecord>(this.attach_TS_QuestRecords), new Action<TS_QuestRecord>(this.detach_TS_QuestRecords));
this._TS_Admin = default(EntityRef<TS_Admin>);
this._TS_LevelType = default(EntityRef<TS_LevelType>);
this._TS_OptionTypeLT = default(EntityRef<TS_OptionTypeLT>);
OnCreated();
this._Quest_QuestID = Quest_QuestIDBL;
this._Quest_Name = Quest_NameBL;
if (Quest_OptionTypeIDBL != null)
{
this._Quest_OptionTypeID = Quest_OptionTypeIDBL;
}
this._Quest_AdminID = Quest_AdminIDBL;
this._Ques_LevelID = Ques_LevelIDBL;
this._Quest_Time = Quest_TimeBL;
this._Quest_Mark = Quest_MarkBL;
this._Qest_Explanation = Qest_ExplanationBL;
this._Qest_IsMultipleAnswer = Qest_IsMultipleAnswerBL;
}
Please help me out from this problem
Honestly, I haven't looked too deep, but it looks like that OnCreated is sitting a little far north... You probably want to call it after you're done setting up your variables. Other than that i'd say make sure you're properly initializing everything in the method calling the constructor.
You can call default constructor like this, it works fine for me:
public partial class MyClass
{
public MyClass(string fieldValue1,int fieldValue2)
: this()
{
this.field1= fieldValue1;
this.field2 = fieldValue2;
}
}
If this do the trick, you can read more about using contructors in C# here.

Categories