is it possible to have partial xaml like partial class? - wpf

I'd like to split a xaml file into several files a bit like partial class : is there a way to do so ?
I want to be able to manage my project files more convenienly.

There are some possibilites, although it may not be exactly what you think about.
You may outsource ressources by means of a ResourceDictionary. This is very convenient for styles and templates. Of course you have to organize your XAML such that you could benefit of it (use ControlTemplates for instance).
Furthermore you could create UserControls that encapsulate parts of your XAML. This depends on your layout, though.
These parts can be organized in assemblies, which you refer to by references known to XAML via xmlns:??? declarations.

One technique that I have used successfully is to create a parent class that inherits UserControl and I use that as my base xaml class. This allows me to centralize functions like 'onLoad', 'onDataContextChange', etc. Between that and using resource dictionaries I've been able to keep my code much more streamlined.

Related

WPF: Multiple XAML files that share the same code behind file

I want to create an application where the user navigates through pages that are placed inside a frame element. The problem is that one page can have different layouts which basically provide the same functionality. There can be a few buttons or input controls more or less per layout, but they all should share the same code behind file.
In Windows Forms, I used to place all elements (the layout) on the same form and then hide/show the controls I required, but that's a very ugly solution and I was hoping that WPF provided something more convenient here.
I tried to create 2 Pages, deleted their respective .cs files and set their "x:Class" attribute to a custom .cs file, but that results in compiler errors (ambiguous calls to InitializeComponent() ).
So can I have multiple pages that share the same code?
You should move the logic from the code-behind class to a view model class. This pattern is known as Model-View-ViewModel and is the recommended design pattern to use when developing XAML based user interface applications.
There are plenty of online tutorials about it and this one should provide a good starting point for you: https://msdn.microsoft.com/en-us/library/hh848246.aspx.
Once you have understood the pattern and implemented your application logic in a view model class, you could then simply set the DataContext property of both pages to the same view model:
public Page1()
{
InitializeComponent();
DataContext = new ViewModel();
}
A code-behind class is simply a partial class, i.e. it is partial definition of the Page that you define in XAML and therefore you cannot "share" this one between several different pages.
Partial classes are just a way of splitting the definition of a class across several different source files: https://learn.microsoft.com/en-us/dotnet/articles/csharp/programming-guide/classes-and-structs/partial-classes-and-methods.

Extending user controls in WPF

I have built a User Control composed, as usual, of a XAML part and a code-behind part. Now, I need to create another User Control which shares some of the functionalities of the former, but which has different looks and might also have additional features in the code-behind.
My first idea was to create an interface to gather the common functionalities of the two types of controls. Is this the right way to go? And how would I manage the different XAML parts I should have? Any advice is welcome.
I would like to add another contribution which I think might be useful to others encountering my same situation.
One other possible solution, which in my opinion is suitable if the controls you are going to create are not particularly complex, is to create a base User Control containing the common features that you want to share: such control will be written entirely in C#.
This, in fact, allows inheritance in User Controls composed of both XAML and code behind. In the XAML of the inherited control, rather than having
<UserControl> ... </UserControl>
You will have
<MyProject: MyBaseControl x:Class="MyProject.MyExtendedControl"> ... </MyProject: MyBaseControl>
and then in the code behind you will also need to specify the following:
class MyExtendedControl : MyBaseControl
Hope this helps.
User controls don't lend themselves well to inheritance in WPF, you can do some hacks to make it work, but overall you'll probably be better off using a Custom Control instead. It's easier to specify different XAML for inherited controls using this technique. The easiest way to get started with a custom control is to add a new item to your project of type "Custom Control (WPF)" and it will add the control and the XAML gets added to Themes/generic.xaml for you.
To inherit from this control, the easiest way is to add another new Custom Control (WPF) and then change the code behind to inherit from your parent control instead of Control.
There are a number of ways to split up the pieces to make them easier to work with.
MVVM, as mentioned in a comment, relies upon Data Binding to separate the input controls from logic. By setting the appropriate class which implements INotifyPropertyChanged into the DataContext of you control, you can change the behaviour. Your DataContext class or ViewModel could implement Visibility properties to show and hide different parts of the input if the differences are not too great between the uses.
Another way to break apart functionality is by Aggregation. See StackOverflow 269496
You could build smaller controls that implement common functionality and then build larger special purpose controls by combining the smaller controls (i.e. aggregating them) to make the larger control. Aggregation will work for both the code-behind and the Data Binding approaches.

viewmodel have to be public. How should I deal with that?

Pretty much it summarizes my problem here:
Double check - does it ever make sense to have internal viewmodel class?
I have controls.DLL and I'd like to keep this custom control bindings and viewmodel's internal. However, this doesn't seem to be possible.
How do you get around that? The only way I see it - don't use bindings..
Why do you have a view model for a custom control? I assume you're assigning the view model object to the DataContext property, but this is almost always a mistake: the DataContext should be available to consumers to use and abuse as they please. Stated another way, what happens if a consumer of your custom control explicitly sets the DataContext? It sounds like your control will stop working and throw a bunch of xaml binding errors.
A custom control is inherently lookless. There is no model or view model, just a view. That view is the .cs file. You supply a default look via your themes/generic.xaml file, but consumers should be able to supply their own template. If you're tying them to a view model, they also need to know how to create a view model instance and all of its dependencies. You've just created highly coupled code. DI containers can loosen the coupling, but that just downgrades the relationship between classes from "coupled" to "related". I say, why do consumers even need to know that information?
A better approach is to provide all of the properties for your control as dependency properties. Then your generic.xaml can provide a control template that uses the more efficient TemplateBinding to bind properties/objects to your control. If you need to populate these dependency properties from a business object, expose another dependency property of type IBusinessObject and set the derived values in that object's PropertyMetaData changed handler. If your IBusinessObject type contains a property which is yet another class which implements INotifyPropertyChanged, you should probably (1) rethink your object graph or (2) create a Bnding object in code using the subclass.
I think following all of the above advice will eliminate the problem about which you're concerned plus the other problems as well. Leave the view models to the UserControls. And yes, this is why custom controls are a MASSIVE headache. Doing them right is fairly involved.
Try protected internal. I suppose this should work. Although I don't think its good idea to have the ViewModel not public at all, cause one of the purposes of it is to be able to define several Views against the same ViewModel, which may come from different assemblies.

What's the recommended way to expose standard colors in WPF

I would normally just create a static class like StandardFooColors and create a static field for each standard color. However, with WPF I could also put these in a resource dictionary. Just wondering if there is a recommended way to do this or if it is 6 of 1 or half dozen of the other?
I suggest you use a ResourceDictionary.
This will also give you the option to associate color (xaml) files with different "skins", and easily switch between them on-the-fly.
Plus, it is easier to define complex colors and brushes in xaml than it is in code.

Is there a way to follow a binding in code?

If i have a Binding which has a property path and the data source can i execute it in code, to find the value?
The path that i am trying to follow can be quite complicated, including collection lookup and multiple levels.
there is a hack :
create a content control
use BindingOperations.SetBinding()
then retrieve the content
is there a better way?
You can avoid using a ContentControl, and write your own very simple class that derives directly from DependencyObject, and provides a single DependencyProperty, which you can then target with the binding. Aside from that, no, there isn't any better way - binding machinery in WPF is very much tied into the concept of dependency properties, and a binding cannot really be a "free-standing expression" that is just evaluated.

Resources