Add view directly to xaml with Caliburn Micro - wpf

I'm still experimenting a bit with Caliburn Micro and I can't seem to find a way to directly add a view to a xaml without adding another ContentControl with a property in the viewmodel behind it.
I can place this: <views:TheView ... /> in the xaml but then it can't find the target actions so it seems it doesn't find the viewmodel behind the view.
Is it possible to directly declare a view in a xaml without a ContentControl, and how?

You will have to tell Caliburn to bind the view model to a user control.
In the definition of "TheView" are you able to add the following line to the UserControl element:
cal:Bind.Model="TheViewModel"
So it will look similar to:
<UserControl x:Class="Example.Views.TheView"
cal:Bind.Model="Example.ViewModels.TheViewModel" ...
While looking into this I did find this answer to another StackOverflow question:
Does Caliburn.Micro play nicely with user controls?

Related

How can I bind Text property of TextBox (VIEW) to a vaiable (in VIEWMODEL)

I am a newbie in WPF. I was exploring MVVM Pattern for WPF applications. I am having trouble in binding Text property of a TextBox from VIEW to a variable in VIEWMODEL
Here is the TextBox from MainWindow.xaml
<TextBox x:Name="UsernameTxt" Grid.Row="4" materialDesign:HintAssist.Hint="Username"/>
I just need to know how to bind its Text Property to ViewModel Class in Class Library
Thanks
I think it's possible to give a very generic answer to this very generic question.
If the question changes context this answer is very likely to be deleted but here goes anyhow.
You want your viewmodel to be in the datacontext of the textbox. Because datacontext is inherited down the visual tree this usually means you want to set datacontext of your window to an instance of the viewmodel. Or maybe the usercontrol your textbox is in, but we know nothing about your app so let's just cover the simple scenario.
Your options are to instantiate a viewmodel using code or xaml.
If you look at this article:
https://social.technet.microsoft.com/wiki/contents/articles/31915.wpf-mvvm-step-by-step-1.aspx
That instantiates in xaml.
Note the xmlns is
xmlns:local="clr-namespace:wpf_MVVM_Step01"
That's saying where you see some bit of markup which is prefaced "local:" then go get the class out of this namespace.
To point to a different dll ( a class library ) you need to tell it which assembly. You do that by adding ;assembly=Whicheverdll to your equivalent of that xmlns. And of course that won't be local then so give it a different name. You also need a reference to that dll or project added to the entry point exe.
Once you've done all that and your viewmodel is instantiated into memory and in the datacontext of that textbox you need some sort of binding.
Which the article covers but that will be something like:
<TextBox Text="{Binding YourPublicStringProperty}"/>

WPF // MahApps.Metro // Caliburn.Micro // Flyout // HeaderedContentControl

Since a change in MahApps.Metro 1.5.0 the base element of a Flyout was changed from ContentControl to HeaderContentControl. Now the MVVM approach with Caliburn.Micro and this suggestion doesn't work anymore.
Has anybody else tried to solve this issue in a nice MVVM way?
While I haven't tried it myself but since the new Flyout control is now based on HeaderedContentControl it would be a simple logic choice to attempt to do this instead of the previous, which was based on ContentControl. Looks like the advantages of this change were the elimination of a couple of dependency properties...
<controls:FlyoutsControl.ItemTemplate>
<DataTemplate>
<HeaderedContentControl cal:View.Model="{Binding}" />
</DataTemplate>
</controls:FlyoutsControl.ItemTemplate>
The other thing that might come out of this that you create a Caliburn.micro convention to actually bind correctly to that HeaderedContentControl which wouldn't be all that different from the ContentControl variant was, by default in CM already. What is odd is that this HeaderedContentControl is derived from ContentControl in theory it should have been found correctly. Another thing to think about is this actually might also be related to Visual Tree where CM can't see it till it's in the tree, therefore can't bind it.
Content Control convention in CM source as a reference.
I've added posted a work around on GitHub.
It appears there's something going on with setting the ItemTemplate of the FlyoutsControl.

Generic ViewModel that works with ItemsControl

I implemented some generic CustomControls in WPF, for instance an AutoCompleteTextBox.
Now, I'd like to implement a generic ViewModel library, in order to perform the databind of these controls.
Now I defined one attached property named CDataSource, that specifies the source of the data to bind within the control.
My question is : Is it possible, that the CustomControl passes to the ViewModel the CDataSource value? In this way the ViewModel may populate the control on the basis of the CDataSource property.
Thanks in advance
This seems like a strange request to me. You don't want any dependency on your view model from within your custom control. Instead, you would normally have a dependency property on your custom control which is the ItemsSource, and then you would set the value of this from your view in XAML.
This is how the AutoCompleteBox included in the WPF Toolkit operates.

Silverlight: ViewModel trigger function in code behind

I have a bit of a problem with my Silverlight application, and my usage of the MVVM pattern.
In my View I have a DataGrid. The ItemsSource would normaly be bound to the ViewModel, but in my specific case I need the columns to be dynamic and my items collection consists of a Dictionary for each item, so I have no class properties to show. My solution was to generate all this in codebehind, since the actual design of the DataGrid has nothing to do with my ViewModel. This was the only solution I could think of since the columns can't be databound.
I have got all of this to work. My problem is that I'm using RIA and the view has no idea when the items collection has finished loading. I tried my design out by putting an ordinary button on the view to trigger the codebehind function, but obviously this solution is no good. I need my codebehind function to run as soon as my item collection has finished loading.
Can I make my codebehind listen to the ViewModel?
I have a feeling that you are messing up things somewhere.
For your question I think you can solve it by having an event in the ViewModel.
Subscribe to that event in your view's view_Loaded event and call the codebehind function in the handler.
I would recommend you to recheck your design and to see if this is really necessary.
I understand what you mean, we once had to do the same thing generating random columns which is a PIA in silverlight because you would need some kind of object that has a dynamic set of properties.
I see you've found the Dictionary solution. What I would suggest, which isn't per sé the cleanest solution but it is cleaner then putting the stuff in the code behind, is to add this in a converter. Then bind the collection to the itemssource of an itemscontrol and then when the list propertychanged is raised you assemble the datagrid in the converter.
small example:
<ItemsControl Grid.Row="1" ItemsSource="{Binding theListOfEntities, Converter={StaticResource theconverter}}"/>

silverlight adding single prism command delegate to a list of items in xaml

I'm building a menu using Prism (using a trtelerik tree view with hierarchy data templates but hopefully the details don't matter) and I'm trying to set up a Click.Command on each menu items bindings that will all call the same delegate command which is defined in the view model. The menu is built up out of items which I don't really want to put any references to the command in.
How do I bind the command to each of these items in xaml? I've looked around and it looks like in WPF I could use a relative source binding and find ancestors but there doesn't seem to be a way of doing this in silverlight. Can I setup the delegate as a static resource somehow? I don't think I can create a static resource to the view model as this uses Unity to resolve paramters to it's constructor.
One option is to bind to the UserControl's DataContext (or any other control's DataContext) via ElementName binding.
<UserControl x:Name="Control" xmlns:Cal="clr-namespace:Microsoft.Practices.Composite.Presentation.Commands;assembly=Microsoft.Practices.Composite.Presentation"...
Cal:Click.Command="{Binding ElementName=Control, Path=DataContext.SomeVMCommand}"
Here's a similar post.

Resources