loading a silverlight control with a custom constructor - silverlight

I have a silverlight page in which I am loading a control. This control has its own viewmodel which I pass in to the .xaml.cs file thru its constructor. However I get an error when compiling. This is the error:
{No matching constructor found on type 'MySite.Views.SearchFlyOutWin'}
My main page makes a reference to the 'SearchFlyOutWin' like this
xmlns:part="clr-namespace:MySite.Views;assembly=MySite"
In my mainpage.xaml I have tried to load the control like this
<part:SearchFlyOutWin x:Name="searchFlyOutWin" Visibility="{Binding Converter={StaticResource BooleanToVisibilityConverter}, Path=IsSearchVisible}" />
The constructor in my SearchFlyOutWin.xaml.cs is like this
public SearchFlyOutWin(ISearchFlyoutViewModel viewmodel)
{
InitializeComponent();
DataContext = viewmodel;
}
I get the error described above in my Mainpage.xaml.cs when it calls the InitializeComponent(); method.
I think I probably need to direct the clr to call the correct constructor when loading the searchwin in this line here below
<part:SearchFlyOutWin x:Name="searchFlyOutWin" Visibility="{Binding Converter={StaticResource BooleanToVisibilityConverter}, Path=IsSearchVisible}" />
Any ideas on how to correct this? ...Thanks for your time.

.
I have a silverlight page in which I
am loading a control. This control has
its own viewmodel which I pass in to
the .xaml.cs file thru its
constructor. However I get an error
when compiling. This is the error:
{No matching constructor found on type
'MySite.Views.SearchFlyOutWin'}
If your own control's constructor takes some parameter(s), then you cannot use this control in XAML. In XAML, every control must have a constructor with no parameter. That is why, it shows the error message {No matching constructor found on type 'MySite.Views.SearchFlyOutWin'}, since XAML parser searches a constructor with no parameter in your control called SearchFlyOutWin, and it found none!
One soution is that remove the parameter from constructor, and define your Model in the XAML as resource, then set the DataContext to it. Like this,
<Window.Resources>
<local:SearchFlyoutViewModel x:Key="model"/>
</Window.Resources>
<part:SearchFlyOutWin DataContext="{StaticResource model}"/>
Hope, it solves your problem.
.

If you're committed to passing the viewmodel to the object in the constructor (which I don't think is a bad thing), the only way I've found to do this is to create the object in code and then add it to its parent panel programatically. Setting up bindings in code is also possible, though the syntax is more complex than the XAML syntax. The code might looks something like:
SearchFlyOutWin searchFlyOutWin = new SearchFlyOutWin(viewModel);
Binding b = new Binding("");
b.Source = IsSearchVisible;
b.Converter = new BooleanToVisibilityConverter();
searchFlyOutWin.SetBinding(SearchFlyOutWin.VisibilityProperty, b);
SearchFlyOutWinParentPanel.Children.Add(searchFlyOutWin);
Where SearchFlyOutWinParentPanel is some panel that can accept children. If there's an alternate way to do this in XAML, I'd love to see it, but I haven't found it yet.

You may need to set you viewmodel class to be public.
Because I guess your viewmodel class will be in another namespace other than view.

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}"/>

Cannot set DataContext of custom UserControl declaratively

I have created a small UserControl named EventMenu. I reference it in a larger view using:
<views:EventMenu
Grid.Row="1"
DataContext="{Binding DataContext.ServicingEventsMenuViewModel}"
/>
(I've also tried DataContext="{Binding Path=DataContext.ServicingEventsMenuViewModel}").
However, no content from the bound data context appears in the control (static content from the control's XAML file does appear). I believe the control is not binding the DataContext.
In the code behind constructor for the UserControl, I've done this:
public EventMenu()
{
InitializeComponent();
if (DataContext == null)
{
Console.WriteLine("No data context!");
}
}
and it does indicate that the DataContext is null.
What do I need to do to ensure that the DataContext is set on my UserControl?
The first wrong thing i see is this :
DataContext="{Binding DataContext.ServicingEventsMenuViewModel}"
DataContext is a Dependency Property of FrameworkElement.
So when writing something like you'v written , you wrote it as if your DataContext had a property called DataContext , it's the equivalent of writing this :
DataContext="{Binding Path=DataContext.ServicingEventsMenuViewModel}"
Are you trying to reach a parent element's DataContext ?
if so you need to write something like this ( for example if it's parent is a UserControl):
DataContext="{Binding Path=DataContext.ServicingEventsMenuViewModel,RelativeSource={RelativeSource AncestorType={x:Type UserControl}"
I'm guessing that's the case here ...
let me ask you this , post the xaml in which
<views:EventMenu />
is nested and the class holding ServicingEventsMenuViewModel property .
The second thing i think is wrong is to checking if your DataContext is null in the constructor , even if you did write the correct binding statement this property would still be null in the constructor.
subscribe to the FrameworkElement's Loaded event and check it there.

Get reference to Xaml object in view model

I have a an object created in Xaml:
<Grid>
<MyObject/>
</Grid>
I need someway to bind the object myObject back to a property in my view model. I dont know whether this is possible, everything ive seen so far binds properties together, but any help would be greatly appreciated.
I am assuming what you want is your ViewModel to hold the actual visual control MyObject in it and your Grid to display it via MVVM.
This is possible through ContentControl in WPF.
Assuming your ViewModel has a property MyObjectView which holds MyObject...
<Grid>
<ContentControl Content="{Binding MyObjectView}" />
</Grid>
Having said that you must take caution that same MyObjectView is not bound to any other content control as that will result in an error
"Specified element is already the logical child of another element.
Disconnect it first"
And if that requirement is possible then you must excercise ContentTemplate option.
Let me know if this helps.
It is possible. It kinda breaks mvvm though.
You can attach an InvokeCommandAction to this object, and bind the CommandParameter to it via ElementBinding. Then in the callback of the command which you defined in the viewmodel, you will have a reference to this object from the CommandParameter.

How to initialise my WPF app using MVVMLight?

I am building a WPF application using MVVM Light and having problems tying up my Views to my View Model. I have a view model in which I am passing in an Interface of IDataContext, which is basically passing in a datacontext.Then I have an View which I have inserted the following statement on top
DataContext="{Binding MyViewModel, Source={StaticResource Locator}}"
In my ViewModelLocator I have added the following lines :
IoC.Register<IDataContext, MyDataContext>();
and
IoC.Register<MyViewModel>();
And after putting a break point in the constructor of the 'MyViewModel', the breakpoint gets hit. Is there something I am missing, please help???
Did you define a public getter for your viewModel in ViewModelLocator class as shown below?
public MyViewModel MainViewModel
{
get
{
return SimpleIoc.Default.GetInstance<MyViewModel>();
}
}
and then use the "MainViewModel" in the view binding as shown below
DataContext="{Binding MainViewModel, Source={StaticResource Locator}}"
What kind of behavior you see? Empty view window with no datacontext set? OR exception when displaying your view?
You can have a look at this http://nileshgule.blogspot.com/2011/05/integrate-mvvmlight-toolkit-with-basic.html

How to bind XmlDataProvider.Source to MVVM property

I've got a treeview bound to an XmlDataProvider following this example. The app I am working on is following the MVVM pattern and the Xml is from a file that the user will open.
When I try to bind the Source property of the XmlDataProvider like so
<XmlDataProvider Source="{Binding Path=XmlFilePath}"/>
I get a "Binding can only be applied to a DependencyProperty of a Dependency object." or somesuch.
So short of cobbling the binding together procedurally is there a way to declaratively bind the XmlDataProvider Source? If I try to forgo the data provider and bind the tree directly to an XmlNode property I get an error about using XPath binding only with Xml objects; which makes absolutely no sense to me but I'm sure it's trying to tell me something important.
The answer appears to be: you can't.
I was able to solve my underlying problem (binding a treeview to an Xml document) by removing the XmlDataProvider from the equation and binding the TreeView directly to a ViewModel property that returns an XmlNode.
What had been tripping me up was that I took the binding code that pointed at the XmlDataProvider and pointed it at my property, leaving the XPath argument in place.
<TreeView ItemsSource="{Binding Path=ProjectDocument XPath=.}">
This would result in a runtime error: System.Windows.Data Error: 44 : BindingExpression with XPath cannot bind to non-XML object.; XPath='.'
Which was not the most helpful. What it was really trying to say is that you can't bind to an XmlNode property AND provide an XPath argument in the binding (because it's the XmlDataProvider that knows what to do with that??).
<TreeView ItemsSource="{Binding Path=ProjectDocument}">
actually that was rather tough problem for me, cause I needed the app to load treeview from temp file, and assuming application can have different locations, I can't set strict link in the XmlDataProvider Source property;
Add source as resource to the project
the solution I found is adding temp file (markup is created via XAML, see below) to the project with build action set to Content thus, application reloads it every time you call InitializeComponent() on the object containing XmlDataProvider and my treeview updates.
<XmlDataProvider x:Key="dshPreview"
Source="~tmpConstruct.xml"
XmlNamespaceManager="{StaticResource argNms}"
IsAsynchronous="true"/>
TreeView is bound like this:
<TreeView x:Name="PreviewTree"
ItemsSource="{Binding Source={StaticResource dshPreview},
XPath=/mns:engine/mns:ws}"
/>
Maybe this will help someone
I didn't find how to bind the source straight away, but you can change the XmlDataProvider source in the code behind as following:
var xdp = (XmlDataProvider)this.Resources["key-of-your-XmlDataProvider-in-resources"];
xdp.Source = new Uri("http://url-of-your-xml");
You can use that combined with an event handler to bind.

Resources