Catel and DevExpress DockLayoutManager don't work together - wpf

I use Catel and DevExpress DockLayoutManager in my application. I wanted to use this code to automatically create a View Model:
http://gyazo.com/147dff382d16e08cee0270ac20c6b330
http://gyazo.com/24a4ec62e90d49b4e08e3ba1d1790b59
but I can not run the application after compilation.
If we replace catel:UserControl on UserControl then everything works fine:
http://gyazo.com/b69a0257d992bb13c19813c055d47d92
, but goes without is not created ViewModel.
I wanted to use IUserControl but it has not helped. UserControlLogic does not perceive DocumentPanel as UserControl:
http://gyazo.com/e5596231404c054e459db06446ab57ee.

The reason for this is that DocumentPanelEx (and thus DocumentPanel) does not derive from UserControl. I will investigate if the base class being used can be turned into ContentControl instead of UserControl (but then the question is: from which class does DocumentPanel derive?). If you want us to investigate, please add an issue to the backlog at http://www.catelproject.com/support/issue-tracker/
For now you should put a UserControl as root into the DocumentPanelEx. I know it's not the ideal situation, but it will solve your problems for now.

I've reviewed your project from ticket Catel and DevExpress DockLayoutManager don't work together and it seems that the issue is caused by the Catel UserControl. On startup it tries to recursively find the InfoBarMessageControl in the visual and logical trees. If there is no such control and the visual tree is large, this operation may take a long time. I suggest you wrap the DockLayoutManager in the InfoBarMessageControl, this should resolve the issue.

Related

Drag and drop from datasource to WPF window not working

I have been tasked to design a contact management program for my company. We have VS 2012 and since I have never used WPF before I thought I would use it to develop this application.
I am having huge problem getting started on the binding when utilizing the entity framework for the database which btw is database first.
I have followed the instructions within this link to the letter.
http://msdn.microsoft.com/en-us/data/jj574514.aspx
The objects show up in the data sources window just fine. But when I drag and drop to my window, nothing happens. No idea what I am doing wrong and cannot find anyone else with this problem.
Can anyone help me out here? I have looked everywhere. Any help is appreciated
Ok. I actually went thru that article, just to show good faith and let you know that I actually want to help you.
I came to the following conclusions:
That article show a very basic scenario of getting data from an Entity Framework context and showing it in a WPF DataGrid.
It doesn't have any kind of validation nor business rules.
It doesn't have any UI behavior such as conditionally enabling/disabling or showing/hiding any UI elements.
That kind of scenario is where the Designer is useful, when you don't actually need anything except getting / saving data from / to a DB.
Unfortunately (or fortunately for all of us developers who make a living of it), most applications will require some level of validation and business rules and some level of UI logic.
The designer is really useless when it comes to developing complex logic.
You can use the designer for such situations where you don't require complex logic, however I must warn you the following cons:
The Visual Studio WPF designer produces fixed-size, fixed-position UIs. these type of UIs don't work well when executed in computers with different screen resolutions and DPI settings. Just like winforms.
It also produces XAML that has many unnecessary things (such as x:Name="categoryIdColumn" and things like Margin="13,13,43,191" which are really bad from a maintainabilty / scalability point of view)
From what I've seen, the designer-generated XAML also contains a CollectionViewSource, this is both a good thing and a bad thing. It's a good thing because it enables Design-Time Data in the DataGrid, but it is also bad because it bloats your XAML with lots of unneeded things and introduces unnecessary <Window.Resources> that complicate things up.
Now, this is the very minimal XAML needed for that DataGrid, without Design-time data support:
<Window x:Class="MiscSamples.DesignTimeDataGrid"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DesignTimeDataGrid">
<DataGrid ItemsSource="{Binding}" AutoGenerateColumns="False">
<DataGridTextColumn Header="Category Id" Binding="{Binding CategoryId}"/>
<DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
</DataGrid>
</Window>
You see? It's actually faster to type that (much more so with the help of Intellisense) than what it takes for you to browse the property window and set these properties manually.
My suggestion is that you get familiar with XAML instead of insisting in the hard way to do things
Another very important aspect to keep in mind is that generally speaking, you don't put anything in code-behind in WPF because it's not needed, therefore that tutorial is actually going against the WPF Way of doing things, but that's Ok because it's actually an Entity Framework tutorial, not a WPF tutorial.
ease of development
You really need to reconsider what you call "ease of development". When it comes to UI development, I call "ease of development" to actually being able to do what I want with the UI without having to resort to shitty procedural code practices involving P/Invoke (whatever that means) and "owner draw" type of things for evertyhing.
WPF provides REAL ease of development as opposed to the fake ease of development exhibited by winforms
winforms lets you do everything with a designer (and this is just because the code the designer generates is actually so shitty that nobody would have ever used winforms if they didn't have the designer) but then when it comes to adding complex DataBinding or UI logic you're stuck with winforms' incapabilities forever.
WPF encourages manual XAML writing, not only because XAML is declarative (as opposed to the procedural winforms approach), but also because the levels of customizability and reusability are so high that a designer-centric approach does not make sense.
drag and drop is the easy way out
No it's not. It's actually the hard way. The easy way is to learn XAML and be able to do Things you can't even imagine to do with winforms.
If a designer-centric approach still makes sense to you, you may want to try Expression Blend
Automatically Create Data Grids from Your Models
Using a data source to drag and drop a template onto a WPF control is an excellent and fast way to get up and running!
Start by doing this: In your project create a folder named Models, then use either Entity Framework DB first or code by hand the models you want to show.
OR see discussion below on Object binding...
In that same folder create a dummy class that is a property for IEnumerable like this..
public IEnumerable<MyClassModel> MyCollection { get; set; }
From there go to the Main Visual Studio menu, to View/Other Windows/Data Source and click that link.
Click on Object and find the MyCollection property just created above.
Now open a user control or window in WPF but keep the datasources toolbox opened.
It should default to a DataGrid, but you can right click on the datasource and change it to detail, datagrid or select individual properties of the class it represents.
Simply drag that datasource onto the XAML's grid area. The right click on the new stuff you see and click reset to set the content to be the size of the entire window.
After having done this you will have code injected into the code behind of the view as follows in the window loaded event of that window, usercontrol etc.
// Do not load your data at design time.
if (!System.ComponentModel.DesignerProperties.GetIsInDesignMode(this))
{
//Load your data here and assign the result to the CollectionViewSource.
System.Windows.Data.CollectionViewSource myCollectionViewSource = (System.Windows.Data.CollectionViewSource)this.Resources["Resource Key for CollectionViewSource"];
myCollectionViewSource.Source = your data
// }
Go back to the XAML and look for the CollectionViewSource KEY property that was also inserted when you dragged the property to the XAML. It looks like this:
Use the Key name in the code behind, and then "Bind" the CVS to your data source which is an enumerable of type MyClassModel it can live in the View Model or in the code behind of the view as you choose.
If you only use the CollectionViewSource to as the datacontext of the grid you do not need to implement INPC for any underlying collections! The CVS updates the view automatically everytime the source is updated! Once you get good at this you can create working View prototypes of data in 2 minutes! Forget hand-coding XAML that just takes too long.
Object Binding
Create a static class with a static method that returns something like this:
When using the datasource wizard choose the "Object" selection.
Click Ok and you should see something like this:
You have just mapped all of the properties into the data source definition.
For anyone finding this issue in VS 2022: as per this is written, VS 2022 has this known bug unable to drag and drop data source to XAML form.
More info: https://developercommunity.visualstudio.com/t/drag-a-a-table-from-datasource-and-drop-in-a-windo/1660788
UPDATE:
It says that the fix has been released on 15th June. You can try updating your VS 2022 to the latest.

VS2010 Winform designer alterate decent code

I'm encountering a problem with the WinForm designer. I made a new UserControl, I added a DataGridView, some other elements and a TreeView. With the gui I named all those new components. Now it's time to code that stuff and I realise that the designer missnamed my node of my TreeView. The Designer also added new columns from my DataSource even if it was set to AutoGenerateColumn to false. I though: "Well time to clean some Designer crap again..." and I cleaned that stuff up in the InitializeComponent function (I know it's labeled "Do not modify with the code editor" but... do I have the choise?
Anyway, my problem is : When I go back on the Design view, the VS Designer seems to regenerate the code back but not even how it was. Now the designer declares my DataGridView and my TreeView as local members of InitializeComponent function. I can easily repair and undo my changes but I would like to understand and know if there is a way to disable the auto code generation of the designer.
Also, I tried to make another function which have all what I need so the designer don't screw it up and call it into the initialize component. This solution works at run time but not on Design view. I'm kinda low.
As far as I know, the short answer is no. If something is marked as Do not edit due to code generation., then do not edit it :). I would suggest reading up on partial classes, as that is how you can modify classes without actually messing with the auto generated code. In your case, you will need to go into the designer and fix everything there so that the auto generation works as you expect it to.

Why does my WPF view not work without code-behind when applied through a DataTemplate?

I'm working on a large WPF project using MVVM. We're currently still deciding the extent to which we'll use code-behind, but so far we've gotten along fine with none at all (except for InitializeComponent on windows). However, I recently started using typed DataTemplates to apply views to my view models, and it seems these views, like windows, do not work without the InitializeComponent call, when, according to this article, I thought they would. The DataTemplate just declares a view. When I delete the view's code-behind file, the view model renders completely blank. When I leave it in, it's fine. Any ideas why I might be seeing this behavior?
First, you may be overlooking something important: I used that article heavily when learning MVVM/WPF as well, and I never thought it suggested eliminating InitializeComponent calls from the View.cs.
In fact, doing a quick search reveals the following (under Relaying Command Logic) [emphasis mine]:
Every view in the app has an empty
codebehind file, except for the
standard boilerplate code that calls
InitializeComponent in the class's
constructor.
I've been applying the same pattern you describe while leaving the default code-behind for each view in place, and so far it's smooth sailing. :)
Further: If you check out the definition for the default InitializeComponent(), you'll see that the generated code contains the following statement:
System.Windows.Application.LoadComponent(this, resourceLocater);
I haven't tested to make sure this is the case, but I'll wager a fiddle of gold against your soul that preventing that line from executing is going to affect the rendering of your view... ;)
According to djacobson, even the solution by Josh Smith that I referenced in my question cannot render its views without the code-behind, so the line stating this can be done is misleading. It seems the only way to avoid code-behind for your views is by not putting them into UserControls at all, but just keeping the XAML directly within a < DataTemplate > tag.

Cannot see named Silverlight control in code

In my first few hours with Silverlight 3, as an avid WPF user, I am greatly disappointed at the many things it doesn't support. This seems like an odd issue to me and it's so generic that I cannot find anything online about it.
I have the following XAML:
<controls:TabControl x:Name="workspacesTabControl" Grid.Row="1"
Background="AntiqueWhite" ItemsSource="{Binding Workspaces, ElementName=_root}"/>
However, I cannot see the workspacesTabControl in code-behind. I thought maybe IntelliSense is just being mean and tried to go ahead and compile it anyway, but got an error:
Error 1 The name 'workspacesTabControl' does not exist in the current context
How do I access controls in code-behind?
EDIT: I realized I've pasted the wrong error - I have two controls inside the UserControl called workspacesTabControl and menuStrip. I cannot get to either one of them by their name in the code-behind.
Just in case, here is the XAML for the menuStrip:
<controls:TreeView Grid.ColumnSpan="2" Height="100" x:Name="menuStrip"
ItemContainerStyle="{StaticResource MenuStripStyle}"
ItemsSource="{Binding Menu, ElementName=_root}"/>
EDIT AGAIN:
I'm not sure if this is helpful, but I've taken a look at the InitializeComponent() code and here's what I saw:
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
public void InitializeComponent() {
if (_contentLoaded) {
return;
}
_contentLoaded = true;
System.Windows.Application.LoadComponent(this, new System.Uri("/SapphireApplication;component/SapphireMain.xaml", System.UriKind.Relative));
}
It seems that it simply loads the XAML when it runs (not before or during compilation) so the menuStrip and workspacesTabControl names don't actually get registered anywhere (as they usually are in WPF/win Forms). Could that attribute be a problem? And where do I get rid of this requirement for all the future UserControls I make?
Check the properties in VS for the xaml file itself... make sure the Build Action is set to Page.
As ridiculous as it may sound, I have resorted to using FindName() method to access named items in code-behind:
this.FindName("workspacesTabControl") as TabControl
I realize that this is a ridiculous way but I am forced to use this for now. Please let me know if someone else has encountered this problem and have come up with a better solution!
When you first create a control, Visual Studio does not pick it up with intellisense. However, after you try to build the project, it should become availble. You can also just type the name in without intellisense and then build it. Haven't verified this, but I heard this was on the list of things to fix in SL4.
That being said, if you name a control inside of a datatemplate, that control is not directly accessible in code-behind. This is the same for WPF, though.
You should be able to see it in the codebehind, that part works the same as WPF, maybe if you fix the problem with the menuStrip, then visual studio will be able to build the xaml paty of the page and ull be able to access the tabcontrol
I've seen the same problem in my Silverlight development. Specific to my problem my named controls were nested inside other controls (i.e. a datagrid) and I was unable to access them in my code behind. Any named controls at the same nesting level or above the previously mentioned datagrid worked fine but anything inside it was lost into the abyss.
As already mentioned, it should just appear in Intellisense, however the fact that you're getting an error related to something else, i.e. "menuStrip" is probably interfering with Intellisense. Resolve that error and you'l probably find that you can access the "workspacesTabControl" control.
Are you possibly using some sample code or something where they've named a control "menuStrip" and you've renamed it?
Good luck
Check that you don't have any controls using the same class name as a namespace name. For example:
namespace Solution.ProjectName.workspacesTabControl
{
public class workspacesTabControl
{
...
}
}
This will also give you this error.
Good luck,
Mark

How to use inheriting in WPF

I try to use inheriting in WPF. I have asked a question about this earlier, but no one answered correct. So I try to make a BaseWindow class with some UI elements and I want that other windows, that inherit my BaseWindow would have these UI elements. How to do that. My practise with WinForms applications dont work anymore. Maybe there are some simple examples or smth..? Thanks
If you want to inherit from a window, you need to create an implementation of a window in code only, and you can then inherit from this - note that your Window declaration in the XAML would need to change to point to this code, e.g.
<src:BaseWindow xmlns:src="clr-namespace:BaseWindowNamespace" ...>
If you define the base window using XAML, you'll get the following errors:
"'WpfApplication1.Window1.InitializeComponent()'
hides inherited member
BaseWindowNamespace.BaseWindow.InitializeComponent()'.
Use the new keyword if hiding was
intended"
"BaseWindowNamespace.BaseWindow cannot
be the root of a XAML file because it
was defined using XAML"
Now, at this point, I must point out that this is counter to the way that you should handle composition of your window. The "standard" way of doing this would be to use content templates to display user controls which could be swapped and styled to achieve different looks and functionality. In this way, the function of the window becomes that of a harness, and you can achieve a clean separation of content which can be easily implemented using MVVM.
Did you try the BasedOn tag? I don't know about windows, but that's what you use for UserControls AFAIK.

Resources