send selected item as parameter to method in view-model [WPF,Caliburn] - wpf

I have this problem. I use caliburn micro in WPF. In view I have listbox, and I bind on event MouseDoubleClick method in view-model. I would like send as parameter selected listbox item. But I don’t know how do it.
in view I have this:
<ListBox Name="Friends"
SelectedItem="Key"
Style="{DynamicResource friendsListStyle}"
Grid.Row="2"
Margin="4,4,4,4"
Micro:Message.Attach="[MouseDoubleClick]=[Action SendRp(Key)]"
PreviewMouseRightButtonUp="ListBox_PreviewMouseRightButtonUp"
PreviewMouseRightButtonDown="ListBox_PreviewMouseRightButtonDown"
MouseRightButtonDown="FriendsListBoxMouseRightButtonDown"/>
In view model I have this method:
public void SendRp(string key)
{
MessageBox.Show(key);
}
Any advance, thank.

I dont know much about caliburn but my guess is you have to write
Micro:Message.Attach="[MouseDoubleClick]=[Action SendRp(Friends.SelectedItem)]"
also you should either omit the SelectedItem="Key" or use a binding to your ViewModel like this:
SelectedItem="{Binding Key}"

Related

Content Binding not working for Text block when I used it in Treeview Item

I have a Tree View, I am using a Text block inside my Tree view Item.I can not able to bind text for text block When I used "Data context" for my Treeview Item. Can any one help me in fixing this Issue.
here is my xaml code..
<TreeViewItem ItemsSource="{Binding}" DataContext="{Binding XYZ}">
<TreeViewItem.Header>
<StackPanel>
<Image Source="abc.png" />
<TextBlock Text="{Binding BindContent}"></TextBlock>
</StackPanel>
</TreeViewItem.Header>
</TreeViewItem>
in My View Model, I am using
private string _content;
public string BindContent
{
get{ return _content;}
set{_content= value;}
}
In my constructor I am setting value for Content...
It is working fine when I used static content (or) when I am not using
Data context for Treeview Item. but for some other reasons i need to use Data Context.
How can I bind Content for Text block When I used Data Context for Tree view Item...
Thanks in Advance.
I think the problem could be that you are not implementing the INotifyPropertyChanged or you are not raising the notify property changed event. By default the text is null, then you set it in your ViewModel's constructor, but if it is not INotifyPropertyChanged then the view will not be notified.
Hope this could helps you to solve the problem...
Two things you can do,
Make sure your viewmodel implements INotifyPropertyChanged as suggested by Raul Otario and you raise the event on property change,
Secondly, you can use relative source in your binding something like, UserControl if your xaml is on usercontrol else Window
<TextBlock Text="{Binding Path=DataContext.BindContent,
RelativeSource={RelativeSource FindAncestor,
AncestorType={x:Type UserControl}}}"/>
Hope it helps...

Adding resource in code and using it as StaticResource

For some reason I am unable to bind to ViewModel properties within DataTemplates on some controls. The result of the binding itself is unpredictable, sometimes it work, sometimes it doesn't. For this reason I am thinking of exposing the ViewModel in some other way besides setting it as DataContext.
First thought was to add ViewModel to Resources collection. I am using TabControls for UI, so whenever a view needs to be displayed, it is done through Data templates.
<DataTemplate DataType="{x:Type vm:SomeViewModel}">
<vw:SomeView />
</DataTemplate>
In this situation the view is instantiated automatically, and its DataContext is set to ViewModel set in template. Is there a way I can make this ViewModel available to View's Resources (ex with key=viewModel), so that I can use it like this:
<TextBlock Text="{Binding SomeProperty, Source={StaticResource viewModel}}" />
I have tried adding it in code, in the Loaded event for the View:
this.Loaded += (s, e) =>
{
this.Resources.Add("viewModel", this.DataContext);
};
Above code is executed before the error pops up that says static resource is not found at run-time, so the resource was added to collection.
Any ideas what can I do?
You can define ViewModel as a resource in XAML like that:
<vm:SomeViewModel x:Key="ViewModel"/>
If you want to Bind to DataContext in a DataTemplate you can use the following:
{Binding Path=DataContext, ElementName=uc}
assuming that your window/usercontrol name is x:Name="uc" , or as #stukselbax wrote:
{Binding Path=DataContext, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=[UserControl|Window]}}

Binding Telerik RadRichTextBox through MVVM

I can't seem to pick my way through Telerik's terrible documentation for binding through an MVVM situation. We've got the standard view, and view model. The viewmodel exposes a property, 'Body' that is supposed to represent what the user is typing. Here are the relevant lines of xaml:
<telerik:DocxDataProvider
x:Name="DocxProvider"
RichTextBox="{Binding ElementName=editor}"
Docx="{Binding Body, Mode=TwoWay,
UpdateSourceTrigger=LostFocus}" />
<telerik:RadRichTextBox
Grid.Row="1"
x:Name="editor"
Margin="0"
AllowDrop="True"
ShowComments="False"
MinWidth="800"
MinHeight="300"
MaxWidth="1024"
MaxHeight="1200"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Width="790"
Padding="20,20,0,20"
TabIndex="10"
Cursor="IBeam"
IsSpellCheckingEnabled="True" >
</telerik:RadRichTextBox>
But when I set a break point on Body, it never gets hit. What property do I need to bind to so that my view model actually gets the content of the text box?
Have you tried binding to Rtf property of telerik:RadRichTextBox; another thing can be the ordering of your elements, can you try declaring <telerik:RadRichTextBox before <telerik:DocxDataProvider
Also have a look at this thread on telerik forum -
http://www.telerik.com/community/forums/wpf/richtextbox/binding-document.aspx
Did you remember to set the datacontext in the constructor of the xaml.cs file:
public View(ViewModel viewModel)
{
InitializeComponent();
DataContext = viewModel;
}
This is how you hook up the viewmodel to the view.

How to expose commands for a Hyperlink button in Silverlight Telerik Radgrid

To give you background, i am using Silverlight + MVVM and PRISM.
I have some Master data to show in grid and have the first column as hyperlink to the detail data.
I am trying to expose some command for a Hyperlink button, but it doesnt seem to work fine.
Here's my XAML ->
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn Header="Detail ID">
<telerik:GridViewColumn.CellTemplate>
<DataTemplate>
<HyperlinkButton Content="{Binding DetailID}"
Command="{Binding SelectGridItemCommand}"
CommandParameters={Binding}
/>
</DataTemplate>
</telerik:GridViewColumn.CellTemplate>
</telerik:GridViewDataColumn>
... [other columns]
</<telerik:RadGridView.Columns>
Basically, I want to do some processing on the text that is present on the Column name and navigate to the detail page.
Can someone help me here..
I found what I was doing wrong. I had bound an Model object in the viewModel to the Grid and when I wrote the binding command in ViewModel, i dint specify that it needs to change the data context to my viewmodel.
Anyways I eventually wrote an delegate and exposed an event in the Model class and subscribed to that event in the ViewModel where I handled it with my custom EventHandlerArgs.
With Caliburn Micro the binding is seamless, if you name control, let's say 'SelectDetail', the adjacent ViewModel's method should be named SelectDetail as well. Evenmore, if you create a boolean property named as CanSelectDetail there will be an 'automagic' binding to IsEnabled Hyperlikn's property

MVVM ListBox controlling a Content Control

I've been going round in circles with this for a couple of days, and I'm hoping a WPF guru can see where I'm going wrong.
I'm setting CurrentViewModel in code. The Selected item of my ListBox and the Content of my ContentControl bind correctly. But when changing the selected item in the Listbox via the UI the CurrentViewModel is being set but the Content Control is not being updated.
I'm using a data template to map my Views and View Models.
<DataTemplate DataType="{x:Type ViewModel:MyViewModel}">
<View:MyView />
</DataTemplate>
I have a ListBox which is bound to an observable collection of ViewModels. The Selected Item is bound to the current view model.
<ListBox ItemsSource="{Binding MyViewModelCollection}" DisplayMemberPath="DisplayName" SelectedItem="{Binding CurrentViewModel, Mode=TwoWay}"/>
I also have a content control that is also bound to the CurrentView Model
<ContentControl Content="{Binding CurrentViewModel, Mode=TwoWay}"/>
This is the property that they are both bound to
public MyViewModel CurrentViewModel
{
get
{
return _currentViewModel;
}
set
{
if (_currentViewModel== value) return;
_currentViewModel= value;
OnPropertyChanged("CurrentViewModel");
}
}
I've edited the names for clarity and removed formatting information.
Any help greatly appreciated.
Cheers,
Daniel
EDIT: Came across the link How can I debug WPF bindings?. I set a break point on the Content binding and it does indeed only get called once when the binding is first set.
You should not be setting TwoWay as the mode on your ContentControl:
<ContentControl Content="{Binding CurrentViewModel, Mode=OneWay}"/>
This is because you intend your ContentControl to read the value, but never write it.
As an aside, you can also bind the ContentControl to the currently selected item in the collection, rather than to that property by doing this:
<ListBox ItemsSource="{Binding MyViewModelCollection}"
DisplayMemberPath="DisplayName"
IsSynchronizedWithCurrentItem="True"/>
<ContentControl Content="{Binding MyViewModelCollection/}"/>
The "slash" (/) at the end of the collection indicates the current item selected in the collection and setting that current item property is as simple as setting the IsSynchronizedWithCurrentItem equal to true.
A lot of times I find with this combination, I really don't need the extra property on my view model.
Anyway, I hope this helps.

Resources