ReactiveUI bind to DataTemplate - reactiveui

I have an UWP application with ReactiveUI. I have the following in my DataTemplate:
<MenuFlyoutItem Icon="Edit"
Text="{Binding Resources[EditLabel]}">
Since it is a template, I can't access them in my code behind. So how can I setup the binding here?
I tried the Command but then I can only bind to the item itself and not to the ViewModel of the containing view.
EDIT: I adjusted it that way:
<MenuFlyoutItem Icon="Edit"
Text="{Binding Resources[EditLabel]}"
Command="{Binding DataContext.EditAccountCommand, ElementName=AccountList}"
The Binding does work. I wanted now to add a Converter so I can get the clicked object from the eventargs. But when I add a converter it is executed when the page appears and not when the click is executed. Also I do get the bound command instead of the click arguments.

Related

Bind Command to a template view from viewmodel xamarin prism

I use prism on the project. My problem is: i have a View OrdemServicoView and a model OrdemServicoViewModel, OrdemServicoView has a syncfusion list... inside has a DataTemplate with a some propertys pass and i can bind, but when i try use command inside template it doesnt work, the command code is in OrdemServicoViewModel... how can i do that?
OrdemServicoViewModel:
public DelegateCommand<object> ItemSelectedCommand { get; set; }
OrdemServicoView (List):
<syncfusion:SfListView.ItemTemplate>
<DataTemplate>
<templates:OrdemServicoCardView />
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
In OrdemServicoCardView i try to make a button with ItemSelectedCommand binded
The problem you are having has to do with Binding Context. For instance normally within your View your BindingContext is your ViewModel. When working with a DataTemplate inside of something like a ListView your BindingContext is instead whatever data model you may be passing to that ListView as the ItemsSource. The trick therefore is to be able to reference back to the original ViewModel.
<syncfusion:SfListView.ItemTemplate x:Name="lv">
<DataTemplate>
<Button Text="Some Button"
Command="{Binding BindingContext.MyCommand,Source={x:Reference lv}}" />
</DataTemplate>
</syncfusion:SfListView.ItemTemplate>
How we do it is rather simple, first you need to provide a name on an element that has our ViewModel as it's Binding Context. You can pick anything you like really, I usually just reference the Parent Page but the actual List View will work just fine as well. Next we need to add that named element as the Binding Source. Finally we need to realize our new Binding Context is the Element we added as the Source, so we must prepend our Binding with the BindingContext property to have the proper scope into our ViewModel.

How to add a button to first item in ListView

Greeting,
I'm developing an apps for Windows Phone 8.1 and face some problem with ListView.
I wanted to place a button for the FIRST item in ListView, but it seem like I can't align center the button.
Below is the code I use currently:
<ListView>
<Button Content="Jio!" Height="6" Width="362"/>
<ListViewItem Content="ListViewItem"/>
</ListView>
Adding horizontalalignment='center' just wont work for the button.
The reason I want to do this is because I wanted the button to scroll together with the list, hence I'm placing it inside the ListView.
Please advice what can I do to achieve my purpose, thanks!
I recommend using the ListView.Header content to place such a button instead of adding it as a child directly.
<ListView>
<ListView.Header>
<Button ... HorizontalAlignment="Center" />
</ListView.Header>
</ListView>
By default, the ListViewItems are left-aligned. You will eventually have to replace their Template in order to center-align it (HeaderTemplate Property).

WP7: Listbox item template doesn't work when edited?

**UPDATED**
Just something quick, hope you guys can help me but i'm having this problem where I open up my wp7 project in blend and i edit the listbox item template and i finish it but. I save everything and go back to VS2010 for Windows phone and hit debug but i look at the phone and i have no items showing up at all. The listbox is just blank.
Code:
<ListBox toolkit:TiltEffect.IsTiltEnabled="True" x:Name="ListBox1" FontSize="42.667" FontFamily="Segoe WP SemiLight" IsSynchronizedWithCurrentItem="False" d:LayoutOverrides="VerticalAlignment">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="sp">
<toolkit:ContextMenuService.ContextMenu>
<toolkit:ContextMenu IsZoomEnabled="False" >
<toolkit:MenuItem Header="Delete" Click="Delete_Click" Name="MenuItem1" />
<toolkit:MenuItem Header="Edit" Click="Edit_Click"/>
<toolkit:MenuItem Header="View" Click="View_Click"/>
<toolkit:MenuItem Header="Share.." Click="Share_Click"/>
</toolkit:ContextMenu>
Quick Brief
The app I'm making is a simple note app which saves notes in to a folder in the isolated storage. It successfully retrieves the items but i just want to make it so that it has the title and a brief description. This is all in one item. I've got to that point and the 2 textblocks have ="{Binding}" this basically just adds the title I'm assuming but i also added the ="{Binding}" to the second textblock so its basically showing the title for both of them. Is there a way to bind it to a specific item? like the second textblock, how can i bind that so that it shows 1st 12 characters inside a text file so basically it just shows the title and a brief description?
Maybe you have designtime-only data?
In case you're using Mvvm Light DataService approach, you define 2 DataServices: one for designtime and another for realtime.
Just random assuming. it would be nice to see some sample.
UPD: you posted wrong code, this one is about ContextMenu. I dont see binding there.
But again, generally talking, there shouldnt be any problems. You just deserialize data into model, say
public class Note
{
public string Name {get; set; }
public string Content; {get; set; }
}
And then you have List (or even ObservableCollection if you want realtime changes like renaming). And then you just bind
<TextBlock Text="{Binding Name}"/>
<TextBlock Text="{Binding Content}"/>
If you want to have a strict limit for Content/Description of 12 characters, you can add either Converter and take only 12 first characters, or introduce new property
class Note
{
***
public string Description { get { return Content.Substring(0, 12); } }
}
UPD2:
Ok, lets start from the very beginning. First, MVVM is recommended pattern for Wp7 applications. I believe, you can google info about it yourself, but here are the most important parts:
Model. Keeps your data (in your case, it is notes names and description).
ViewModel. This is abstract view. You have all logic here, you have all data prepared to be rendered here, but VM have no idea how to render data. In your case, a list of notes would be here.
View. Here is description of your ui. In your case, ListBox would be here.
So, first, make a new project, then use NuGet to install latest Mvvm Light (for example). After installing, you should see folders for viewmodels and models.
Create new class Note, like i described before. It would be your model.
Now, go to viewmodel. In a constructor, add a list of Notes there, call it ListOfNotes. Add manually several items to the list and initialize them (add some random values for Names and Contents fields).
Now, go to view. In the top of the file, there should be something like DataContext = "{Binding MainViewModel, Source={StaticResource ViewModelLocator}}". Inside of the view, add ListBox. It should be something like
<ListBox ItemsSource="{Binding ListOfNotes}" >
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}" />
<TextBlock Text="{Binding Content}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
So, what would happen now. When you would run your app, your view would be initialized. It would get MainViewModel (because is it set as DataContext, in step 4). In the constructor of MainViewModel, a ListOfNotes would be initialized (see step 3). Then, when page would load ListBox, it would try to find ListOfNotes inside of DataContext (MainViewModel in our case). It should find your list of Notes, and then, every element of the ListBox would be associated with every element of your ListOfNotes. As it is described in DataTemplate, it would try to get Note.Name and Note.Content.

Window Phone 7 and MVVM, Loaded event of a Page

Hi, I have a problem using the MVVM pattern after I instantiate my view model in this way:
<phone:PhoneApplicationPage.Resources>
<local:DetailVM x:Key="DetailVM"/>
</phone:PhoneApplicationPage.Resources>
How do I know when this Page is Loaded?
You can use the Blend SDK and add an event trigger that triggers a command in your viewmodel.
include
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
in your xmlns includes, and then add a trigger for the Loaded event.
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
The LoadCommand is simply a property that returns an ICommand. You should of course either set the DataContext of the page to your viewmodel, or set the source of the binding to the one in your resources.

Windows phone Exception on TwoWay DataBinding of TextBox item of a Listbox

I'm having problems on Binding a TextBox to a string ( same problem for StringBuilder).
Here is the xaml:
<ListBox x:Name="MyList" ItemsSource="{Binding ListOfBullets, Mode=TwoWay, Converter=StaticResourcedebugConverter}}">
<ListBox.ItemTemplate>
<DataTemplate>
<local:TaskStepControl Text="{Binding Mode=TwoWay}" AddHnadler="{Binding DelegateForHandlingAddTaskStep, ElementName=uc}"></local:TaskStepControl>
</DataTemplate>
</ListBox.ItemTemplate>
and the Items for the ListBox is:
public ObservableCollection<StringBuilder> ListOfBullets{get{....} set{....}}
I also tried :
public ObservableCollection<string> ListOfBullets{get{....} set{....}}
If I run the app I get an unhalted exception "The parameter is incorrect. "
If I remove Mode=TwoWay then it works but as expected editing the Textboxes don't change the text bound object in ListOfBullets;
What am I doing wrong?
MSDN says that you can't have a two-way binding with an empty property path.
I guess the binding engine can perform a two-way binding only to the specific property, not to the object itself.
My thoughts regarding why it is not allowed:
To keep it simple, you can think that the 'writing' part of the TwoWay binding just sets the provided value on your data source object. So this markup Text={Binding Name, Mode=TwoWay} is similar to that C# code: dataSource.Name = textBox.Text on text updates (of course, the entire binding workflow is much more sophisticated and does other things behind the scenes, but that doesn't matter now).
Your sample tries to do something like listItem = textBox.Text, which doesn't update the real item of your ListOfBullets. Please keep in mind that I have dramatically simplified the way bindings work just to give you an idea of what's happening.
What can you do:
Create a wrapper Model class that will contain your string value and bind to
public ObservableCollection<Model> ListOfBullets {get; set;}
with <local:TaskStepControl Text={Binding Value, Mode=TwoWay} />

Resources