change culture using wpflocalizeextension - wpf

maybe it's very simple, but how to change the culture in code behind to allow the wpflocalizeextension to show the desired resource?
I tried to change the application culture, but it did nothing!!

In order to change the current culture at runtime you use the following two statements. With SetCurrentThreadCulture, also the culture of the current thread is updated.
WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.SetCurrentThreadCulture = true;
WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.Culture = new CultureInfo("en");
To get a list of available CultureInfo objects, you can use
WPFLocalizeExtension.Engine.LocalizeDictionary.Instance.MergedAvailableCultures

Try something like this?
CultureInfo.DefaultThreadCurrentCulture = new CultureInfo("en-US");
CultureInfo.DefaultThreadCurrentUICulture = new CultureInfo("en-US");

Related

How to create and use a custom CultureInfo in WPF?

I need a method to display a WPF form with non-standard CultureInfo, which is customizable at runtime. E.g. the customer wants to read dates in "de-DE", but currencies in "en-US". The App should be able to display every currency in the world. Dates and Numberformats are almost "en-US" and "de-DE"
I already tried the "CultureAndRegionInfoBuilder", but it requires admin-rights for the application to register the created culture and it will not update the UI if I use the same name for that culture (e.g. "x-myapp-custom")
In "Application.xaml.vb" at startup:
Private Sub CreateCustomCulture(thisCultureName As String)
Dim myCultureBuilder = New CultureAndRegionInfoBuilder(thisCultureName, CultureAndRegionModifiers.Neutral)
myCultureBuilder.LoadDataFromRegionInfo(RegionInfo.CurrentRegion) 'DE
myCultureBuilder.LoadDataFromCultureInfo(Thread.CurrentThread.CurrentCulture) 'de-DE
Try
myCultureBuilder.Register()
Catch ex As Exception
Debug.WriteLine(ex.ToString)
End Try
End Sub
This is working fine, even if it requires to "run as admin" to register the CultureInfo
In "testwindow.xaml.vb":
Private Sub Testwindow_Loaded(sender As Object, e As RoutedEventArgs)
Me.Language = Markup.XmlLanguage.GetLanguage(Thread.CurrentThread.CurrentUICulture.Name)
End Sub
This is also working fine.
But when I try to change Thread.CurrentThread.CurrentUICulture.NumberFormat.CurrencySymbol = "$" the setting is stored in the CultureInfo, but not reflected the WPF form. Even if I un- and re-register the CultureInfo and set the WPF language again.
I expect to have my bound Textboxes ({Binding TestCurrency, ElementName=testwindow, StringFormat=\{0:C2\}}) to show in "en-US" style (or at least with a dollar-sign), but it keeps showing in "de-DE".

How do you use an Event, given only a name string supplied in xaml?

I've seen in triggers, attached properties, and behaviors the ability to specify SourceObject="myButton" EventName="Click" -- what I want to know is how do you access the event, given its name and owner object, in code? Does this require reflection to implement?
Yes, you use reflection:
var instance = new SomeClassType();
var method = "MyEvent";
var handler = instance.GetType().GetMethod(method);
handler.Invoke(instance, null);

silverlight application wide date

Is there a way to define a application wide format for the dates in Silvelight. So far I've tried to add this code in App_Startup:
CultureInfo culture = (CultureInfo)CultureInfo.CurrentCulture.Clone();
culture.DateTimeFormat.ShortDatePattern = "dd-MM-yyyy";
culture.DateTimeFormat.FullDateTimePattern = "dd-MM-yyyy";
culture.DateTimeFormat.ShortTimePattern = "dd-MM-yyyy";
Thread.CurrentThread.CurrentCulture = culture;
Thread.CurrentThread.CurrentUICulture = culture;
But all my date binding don't take this into consideration.
Regards,
Create a string resource in your App.xaml
<System.String x:Key="MyDateFormat">dd-MM-yyyy</System.String>
And use it as a static resource in your bindings' string format
<TextBlock Text={Binding MyDateProperty, StringFormat={StaticResource MyDateFormat}} />
I haven't tested this, but that would be my first try.
Try accepted answer from here - DateTime Not showing with currentculture format in Datagrid,ListView.
This works for WPF, you can try it for Silverlight to make it respect your culture.
There is a partial solution for this here: http://timheuer.com/blog/archive/2010/08/11/stringformat-and-currentculture-in-silverlight.aspx
This may not work at the application level though - you may need to apply the solution to various other classes e.g. your child windows.

Silverlight InlineCollection.Add(InlineUIContainer) missing?

I'm having difficulty adding the inline of specific type InlineUIContainer into the InlineCollection (Content property) of a TextBlock. It appears the .Add() method of InlineCollection doesn't accept this type, however you can clearly set it through XAML without explicitly marking the content as a InlineContainer, as demonstrated in many examples:
http://msdn.microsoft.com/en-us/library/system.windows.documents.inlineuicontainer.aspx
Is it possible to programatically add one of these as in the following?
Target.Inlines.Add(new Run() { Text = "Test" });
Target.Inlines.Add(new InlineUIContainer() {
Child = new Image() { Source = new BitmapImage(new Uri("http://example.com/someimage.jpg")) } });
Target.Inlines.Add(new Run() { Text = "TestEnd" });
I have a feeling what's going on is that Silverlight is using a value converter to create the runs when specified in XAML as in the example which doesn't use InlineContainer, but I'm not sure where to look to find out.
The specific error I'm getting is as follows:
Cannot add value of type 'System.Windows.Documents.InlineUIContainer' to a 'InlineCollection' in a 'System.Windows.Controls.TextBlock'.
As pointed out by Jedidja, we need to use RichTextBox to do this in Silverlight.
You can't Add() Runs directly, but you can add Spans containing Runs.
Interestingly, you can also do this:
textBlock.Inlines.Clear();
textBlock.Inlines.Add(new Span());
textBlock.Inlines[0] = new Run();
Not that it's a good idea to hack around what the framework is actively trying to prevent you from doing.
P.S. If you can't figure out what XAML is doing, inspect the visual tree.

Refreshing BindingSource after insert (Linq To SQL)

I have a grid bound to a BindingSource which is bound to DataContext table, like this:
myBindingSource.DataSource = myDataContext.MyTable;
myGrid.DataSource = myBindingSource;
I couldn't refresh BindingSource after insert. This didn't work:
myDataContext.Refresh(RefreshMode.OverwriteCurrentValues, myBindingSource);
myBindingSource.ResetBinding(false);
Neither this:
myDataContext.Refresh(RefreshMode.OverwriteCurrentValues, myDataContext.MyTable);
myBindingSource.ResetBinding(false);
What should I do?
I have solved the problem but not in a way I wanted.
Turns out that DataContext and Linq To SQL is best for unit-of-work operations. Means you create a DataContext, get your job done, discard it. If you need another operation, create another one.
For this problem only thing I had to do was recreate my DataContext like this.dx = new MyDataContext();. If you don't do this you always get stale/cached data. From what I've read from various blog/forum posts that DataContext is lightweight and doing this A-OK. This was the only way I've found after searching for a day.
And finally one more working solution.
This solution works fine and do not require recreating DataContext.
You need to reset internal Table cache.
for this you need change private property cachedList of Table using reflection.
You can use following utility code:
public static class LinqDataTableExtension
{
public static void ResetTableCache(this ITable table)
{
table.InternalSetNonPublicFieldValue("cachedList", null);
}
public static void ResetTableCache(this IListSource source)
{
source.InternalSetNonPublicFieldValue("cachedList", null);
}
public static void InternalSetNonPublicFieldValue(this object entity, string propertyName, object value)
{
if (entity == null)
throw new ArgumentNullException("entity");
if(string.IsNullOrEmpty(propertyName))
throw new ArgumentNullException("propertyName");
var type = entity.GetType();
var prop = type.GetField(propertyName, BindingFlags.NonPublic | BindingFlags.Instance);
if (prop != null)
prop.SetValue(entity, value);
// add any exception code here if property was not found :)
}
}
using something like:
var dSource = Db.GetTable(...)
dSource.ResetTableCache();
You need to reset your BindingSource using something like:
_BindingSource.DataSource = new List();
_BindingSource.DataSource = dSource;
// hack - refresh binding list
Enjoy :)
Grid Data Source Referesh by new query instead just Contest.Table.
Simple Solution < But Working.
Whre is eg.
!!!!! Thanks - Problem Solved after no of days !!! but with so simple way ..
CrmDemoContext.CrmDemoDataContext Context = new CrmDemoContext.CrmDemoDataContext();
var query = from it in Context.Companies select it;
// initial connection
dataGridView1.DataSource = query;
after changes or add in data
Context.SubmitChanges();
//call here again
dataGridView1.DataSource = query;
I have the same problem. I was using a form to create rows in my table without saving the context each time. Luckily I had multiple forms doing this and one updated the grid properly and one didn't.
The only difference?
I bound one to the entity similarly (not using the bindingSource) to what you did:
myGrid.DataSource = myDataContext.MyTable;
The second I bound:
myGrid.DataSource = myDataContext.MyTable.ToList();
The second way worked.
I think you should also refresh/update datagrid. You need to force redraw of grid.
Not sure how you insert rows. I had same problem when used DataContext.InsertOnSubmit(row), but when I just inserted rows into BindingSource instead BindingSource.Insert(Bindingsource.Count, row)
and used DataContext only to DataContext.SubmitChanges() and DataContext.GetChangeSet(). BindingSource inserts rows into both grid and context.
the answer from Atomosk helped me to solve a similar problem -
thanks a lot Atomosk!
I updated my database by the following two lines of code, but the DataGridView did not show the changes (it did not add a new row):
this.dataContext.MyTable.InsertOnSubmit(newDataset);
this.dataContext.SubmitChanges();
Where this.dataContext.MyTable was set to the DataSource property of a BindingSource object, which was set to the DataSource property of a DataGridView object.
In code it does looks like this:
DataGridView dgv = new DataGridView();
BindingSource bs = new BindingSource();
bs.DataSource = this.dataContext.MyTable; // Table<T> object type
dgv.DataSource = bs;
Setting bs.DataSource equals null and after that back to this.dataContext.MyTable did not help to update the DataGridView either.
The only way to update the DataGridView with the new entry was a complete different approach by adding it to the BindingSource instead of the corresponding table of the DataContext, as Atomosk mentioned.
this.bs.Add(newDataset);
this.dataContext.SubmitChanges();
Without doing so bs.Count; returned a smaller number as this.dataContext.MyTable.Count();
This does not make sense and seems to be a bug in the binding model in my opinion.

Resources