Refreshing x:Static property bindings - c#

WPF in .NET 4.5 allows binding to static properties using x:Static markup. I'm using it to binding my labels to resource strings. My labels look like this:
<TextBlock Text="{x:Static properties:Resources.SomeResourceString}" />
Application allows localization and user can choose display language from Settings dialog. All translations are in place. The only problem I'm facing is that there is no apparent way of "refreshing" these bindings.
WPF in .NET 4.5 listens to static version of PropertyChanged event, but there is no way for me to raise such an event because Resources class is auto-generated and is not extendable (no partial).
Reloading the application is of course one solution, but I don't want to do that. Interestingly, any labels that are not on screen right now (in a different Tab for example) get updated correctly. It is only the current screen that is not updating.

Related

Is it possible to load XAML runtime in Avalonia

In WPF it is possible to load XAML at runtime and put it in a ContentControl using XamlReader.Load()
Is this possible in Avalonia?
I want to get to a point where I have a user control that contains a content control and based on my configuration, this could point to a file on disk having XAML code to read.
In WPF this works nicely, and the XAML is imported, parsed and the datacontext is inherited, allowing my to put data inside the loaded XAML through my databindings.
I have been searching for an equivalent in Avalonia, but not been successfull.
Install Avalonia.Markup.Xaml.Loader package and use AvaloniaRuntimeXamlLoader class.

How to refresh WPF AutomationElement with DataTemplate - Windows UI Automation

I am trying to automate the testing of a WPF application using Windows UI Automation.
The application has a ContentControl with a data template that changes based on user interaction.
On initial load, I am able to get and click a button inside of the content control. This switches the data template (the sub-controls are removed and replaced with other ones).
However, when I look for the new controls in the automation element, they cannot be found.
I am using the wrapper FlaUI, but I've also tried White and they both have the same sort of result.
I am not using caching, but it seems like the window is somehow cached. Is there a way to reload the element or entire window so that I can retrieve the new controls.
Found the solution on FlaUI's FAQ.
When using DevExpress controls, some things (like tab content) are not
updated By default, DevExpress controls do not raise automation
events, as these events may decrease the application performance. To
make sure that the events are raised properly, set the
ClearAutomationEventsHelper.IsEnabled static property to false on
application startup (needs to be done in the application that is
automated with FlaUI):
ClearAutomationEventsHelper.IsEnabled = false;

XAML/C#: Page/Property Style Changing Efficiency

I am currently working on a WPF project, and I am at an aspect of the program where I don't know how to create the solution efficiently.
Problem:
In my program, I plan on implementing UI versions (Dark mode, Light mode, etc.). Basically just UI color preferences. However, I am unsure of the best way in which I can use the other UI features.
So far, I have set up styles for each UI preferences in the APP.XAML, based on individual properties, such as textboxes and rectangles, and put the general style within the individual pages to be shown.
The UI changes need to be kept within the same SHOWN XAML file so that events can be implemented. I believe it needs to be done by using APP.XAML (which I have already been using this). However, what would be the best way in showing the UI changes? Should I be creating a whole page style? Changing each property individually based on styles? Or is there some better way in completing the UI changes efficiently.
Thanks!
In answer to some of the questions and statements:
The standard templates (see: https://stackoverflow.com/a/45603437/563088) use Themes so that would be a logical first step to follow
It might be easier to maintain separate files with the templates and colors in resource dictionaries although templates will have to be in the Generic.xaml
Do not use events, use Commands and Bindings. If you need to use events, do not hook them up in XAML but hook them up in the OnApplyTemplate of the controls. That way templates can be swapped out and templates are no longer forced to provide specific controls/events as the OnApplyTemplate can search for a control and skip it if it isn't found.
As for switching: from experience I found it easier to define multiple color/brush/resource sets in separate files. Give these colors and brushes the same names (e.g. HighlightBrush, ButtonBorder or CheckBoxCheckGlyph). Depending on the theme you load a different resources file. the templates would simply refer to these resource names (using DynamicResource if you want to enable live switching or StaticResource for switching on restart of the window/app)

System.Windows.ResourceReferenceKeyNotFoundException

i only get the exception in the XAML Editor in visual studio 2010, when i debug the application everything works fine and that resource gets loaded successfully, however the problem only happens in the XAML editor, is there a way to disable such exceptions?
<!--ViewModels-->
<!--This View Model Causes the problem-->
<SharedViewModels:DatabaseViewModel x:Key="DatabaseViewModel"/>
and thats how i use it in the main window
DataContext="{Binding Source={StaticResource DatabaseViewModel}}"
This is a known issue as described in Troubleshooting WPF Designer Load Failures in the UserControl and Custom Control Resources at Design Time section:
By default, UserControl and custom control resources that are available at run time may not be available at design time. When you add your custom controls and user controls to a Page or Window on the design surface, an instance of the control is created. Resources in App.xaml are not available to UserControl and custom control instances loaded on a page or window.
To make your resources available at design time, factor them into a separate resource dictionary and include the dictionary in App.xaml and your control's XAML. Change all StaticResource references to DynamicResource references. The following code example shows how to share a resource dictionary so that its resources are available at design time.
So basically in addition to including your resources in App.xaml you also need to include them in your XAML to make them available at design time. In my experience using DynamicResource instead of StaticResource does not seem to be necessary.

IDataErrorInfo in winforms

Can IDataError info be used properly in a winforms application? In the past I was doing my binding the usual way(1) and did the validation in the OnValidating event of the particular control. I would like to move the data validation to the domain model so that I can easily swap out user interfaces and so that all of the logic is in one place.
I was looking into IDataErrorInfo but everything I find deals with WPF and the app in development is strictly a winforms app.
I also noticed that the binding that gets used in WPF is in System.Windows.Data and the binding that I've always been using is in System.Windows.Forms (which I don't appear to have when I try to add it as a resource - I'm using 3.5).Aside from the property "ValidatesOnDataErrors" is there a difference between the two?
(1) the usual way being:
myControl.DataBindings.Add(new Binding("Text", this.domainModel, "Property"));
This works with the ErrorProvider component in Windows Forms.
For a complete, but very simple and short tutorial, see this blog post.
Yes, IDataErrorInfo works in winforms. For example, DataGridView will use this automatically both per-row and per-cell. But it is implementation-specific, and isn't automatically applied to other bindings. I did once write some code to associate it to an error-provider and do the work via change events, but I don't have it to hand unfortunately. But I seem to recall it wasn't huge.

Categories