Pushpin with EventToCommand - windows-phone-7

I am trying to adapt the UsingBingMaps sample included in the Windows Phone 7 TrainingKit (http://www.microsoft.com/downloads/en/details.aspx?displaylang=en&FamilyID=ca23285f-bab8-47fa-b364-11553e076a9a) to use MVVM-Light toolkit. I am trying to set up a command to the Pushpin's MouseLeftButtonUp event using EventToCommand but the command does not get executed. Below is the code of the pushpin:
<my:Pushpin Style="{StaticResource PushpinStyle}"
Location="{Binding Location}"
Background="{Binding TypeName, Converter={StaticResource PushpinTypeBrushConverter}}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<cmd:EventToCommand Command="{Binding DataContext.PushpinClickCommand, ElementName=HomePage}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<Image Source="{Binding Icon}" />
</my:Pushpin>
Am I missing anything? Was anyone able to use EventToCommand with the Pushpin object?

What are you trying to do with the command?
I can get a command to fire using this, but i cant seem to get the object details from the arguments passed.
I have used this in silverlight, which I think is directly usable in WP7 (please correct me if I am mistaken)
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseLeftButtonUp">
<cmd:EventToCommand Command="{Binding Path=pinSelCommand}" PassEventArgsToCommand="True" ></cmd:EventToCommand>
</i:EventTrigger>
</i:Interaction.Triggers>
In my viewmodel constructor I have
PolySelCommand = new RelayCommand<MouseButtonEventArgs>(PolySelCommandExecute);
in viewmodel class
public RelayCommand<MouseButtonEventArgs> pinSelCommand{ get; set; }
private voidpinSelCommandExecute(MouseButtonEventArgs e)
{
// < Your code >
}
Hope this helps out. If you work out how to pass the object details, please post back as I have problem on this post

Related

Mvvm TextBox KeyDown Event

I'd like to know how I can handle a KeyDown Event with MVVM in my ViewModel.
I have a TextBox and when the user hits a key, which is not a number, the input shouldn't be allowed. I'd normally do it with Code behind like this (not full code, just an easy example):
private void textBox1_KeyDown(object sender, System.Windows.Forms.KeyEventArgs e)
{
// Determine whether the keystroke is a number from the top of the keyboard.
if (e.KeyCode < Keys.D0 || e.KeyCode > Keys.D9)
{
e.Handled = true;
}
}
Now I want to put this somehow in my ViewModel with a Command. I'm new to MVVM and I'm only using Bindings right now (which works fine :) ), but I don't know how to use a Command at all...
My TextBox looks i.e. like this:
<TextBox Text="{Binding MyField, Mode=TwoWay}"/>
ViewModel:
private string _myfield;
public string MyField{
get { return _myfield; }
set {
_myfield= value;
RaisePropertyChanged( ()=>MyField)
}
}
But the setter will only be called, when I leave the TextBox + I don't have access to the entered Key.
I know my answer is late but if someone has a similar problem. You must just set your textbox like this:
<TextBox Text="{Binding MyField, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
The following works for handling the "Enter" key in a TextBox:
<TextBox Text="{Binding UploadNumber, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<TextBox.InputBindings>
<KeyBinding
Key="Enter"
Command="{Binding FindUploadCommand}" />
</TextBox.InputBindings>
</TextBox>
I do this by using the interaction triggers. (this example uses the MVVM_Light framework for the command binding)
here is an example:
<textBox Text="{Binding MyField}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="KeyDown">
<cmd:EventToCommand Command="{Binding MyCommandName}" CommandParameter="YouCommandParameter"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBox/>
Create a ICommand object in your view model with the name MyCommandName and add these to the top of your xaml:
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
xmlns:cmd="http://www.galasoft.ch/mvvmlight"
You don't have to use the mvvm-light command. This is just what I use and I like it because it allows me to use the CanExecute method of the ICommand interface
hope this helps

Binding CommandParameter on ItemsControl Tap event

I'm using an ItemsControl, and I want to identify which item was selected on the Tap command. My xaml is defined here:
<ItemsControl ItemsSource="{Binding AllMyItems}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand Command="{Binding ItemSelectedCommand}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
.... item template ....
and here is my view model:
public RelayCommand<MyItem> ItemSelectedCommand { get; private set; }
public MainViewModel()
{
ItemSelectedCommand = new RelayCommand<MyItem>(ItemSelected);
}
private void ItemSelected(MyItem myItem)
{
throw new NotImplementedException();
}
The event to command works, but when I get to the ItemSelected method, myItem is either Null, or I get an exception casting it (depending on how I define the CommandParameter in the xaml).
I can do this if I use a ListBox and set CommandParameter="{Binding SelectedItem, ElementName=MyItemsList"}
Any ideas on how to do this with ItemsControl? Or does the perf difference not make much of a difference between the two in Mango?
Your Tap Event is occuring on the ItemsControl , you should place your EventToCommand inside the ItemTemplate , some XAML to clear the things for you
<ItemsControl ItemsSource="{Binding AllMyItems}">
<ItemsControl.ItemTemplate>
<...>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand Command="{Binding ItemSelectedCommand}" CommandParameter="{Binding}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</...>
</ItemsControl.ItemTemplate>
...

assigning the result of variable into textblock

I'm trying to get the result of variable into a textblock.text proprety, I'm using
this code:
bool isavailable = NetworkInterface.GetIsNetworkAvailable();
result = isavailable.ToString();
<TextBlock Height="62" HorizontalAlignment="Left" Margin="12,60,0,0"
Name="textBlock1" Text="{Binding result}" VerticalAlignment="Top"
Width="400" Foreground="White" TextWrapping="Wrap" />`
Do you need to keep the binding? The simplest approach here would be to simply use:
textBlock1.Text = result;
However, the better approach would be to use a ViewModel implementing INotifyPropertyChanged with an appropriate property. Then you would make your TextBlock bind to the property, and set the property from your code. The property would raise the appropriate event, and the UI would update accordingly.

Issue binding command parameter in Silverlight

I can't seem to get this to work right. Basically, I have an ObservableCollection that is bound to a list. Inside this collection, I have an object that I need to use to pass as a variable to a Command when it's executed. My plan was to pass this as CommandParameter, but I can't get it to work. The object is actually an Enum value, but I can't get it to work with anything but static text. Below is the code, it's using a MVVM concept using Interactivity(wi)and blend's dll(sl). The property is public on the ListItem, and does implement INotifyPropertyChanged.
Thanks.
<ListBox ItemsSource="{Binding Path=MyList}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<wi:Interaction.Triggers>
<wi:EventTrigger EventName="SelectionChanged">
<sl:InvokeDataCommand CommandParameter="{Binding MyList.ListItem.Property}" Command="{Binding Source={StaticResource Locator}, Path=MyTestPage.TestExecute}" />
</wi:EventTrigger>
</wi:Interaction.Triggers>
...
<ListBox x:Name="listBox" ItemsSource="{Binding Path=MyList}" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<wi:Interaction.Triggers>
<wi:EventTrigger EventName="SelectionChanged">
<sl:InvokeDataCommand CommandParameter="{Binding ElementName=listBox, Path=SelectedItem.Property}" Command="{Binding Source={StaticResource Locator}, Path=MyTestPage.TestExecute}" />
</wi:EventTrigger>
</wi:Interaction.Triggers>
How about doing this? You want to bind to the selectedItem, not ?
MyList is your ObservableCollection ?

Passing Object rather than selectedIndex from Databound listbox

I'm having an issue when I try to pass the selectedIndex of my list from my "List" screen.
On my List screen I have the following binding:
Code Behind:
lbPrograms.ItemsSource = App.ViewModel.Items;
XAML:
<ListBox x:Name="lbPrograms" ItemsSource="{Binding Items}" SelectionChanged="lbPrograms_SelectionChanged">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel x:Name="DataTemplateStackPanel" Orientation="Horizontal">
<Image x:Name="ItemImage" Source="/images/ArrowImg.png" Height="43" Width="43" VerticalAlignment="Top" Margin="10,0,20,0"/>
<StackPanel>
<TextBlock x:Name="ItemText" Text="{Binding programName}" Margin="-2,-13,0,0" Style="{StaticResource PhoneTextExtraLargeStyle}"/>
<TextBlock x:Name="DetailsText" Text="{Binding createDate}" Margin="0,-6,0,3" Style="{StaticResource PhoneTextSubtleStyle}"/>
<TextBlock x:Name="programId" Text="{Binding programId}" Margin="0,-6,0,3" Style="{StaticResource PhoneTextSubtleStyle}"/>
</StackPanel>
<!--<Image x:Name="ItemFavs" Source="/images/favs.png" Height="43" Width="43" VerticalAlignment="Top" Margin="10,0,20,0"/>
<Image x:Name="ItemDelete" Source="/images/delete.png" Height="43" Width="43" VerticalAlignment="Top" Margin="10,0,20,0"/>-->
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
In my detail screen I look up using the selectedIndex value:
App.ViewModel.Refresh();
DataContext = App.ViewModel.Items[index].nValDictionary;
However, since I can't figure out how to just update a value in my iEnumerable collection I have been removingAt[index] and then re-adding to the collection.
So can anyone tell me, how do use update an existing element in my collection? If not, can I pass the programId (that is in my binding) instead of the selectedIndex as the indexes are getting all messed up after the Delete/Add functionality.
Please Advise.
UPDATE:
After speaking in several forums I should clear up that I am implement INotifyChanged Event on my properties in my object.
Basically the following snippet of code is my current issue:
private void FavBtn_Click(object sender, EventArgs e)
{
foreach (var item in App.ViewModel.Items)
{
if ((item.currentProgram == true) && (item.programId != index))
{
item.currentProgram = false;
}
if (item.programId == index)
{
item.currentProgram = true;
}
}
When I run this everything looks to be ok.
However, when I navigate to another page, I re-load the object and the changes are lost. It is almost like I need to save them before navigating, however, if I do a item.Save(); I get duplicates in my list.
I'm guessing you haven't implemented INotifyPropertyChanged on your Items class yet.
Implementing this will allow updates made in these objects to be updated through your data bindings.
Here's a walkthrough on how to implement INotifyPropertyChanged.
How to: Implement the INotifyPropertyChanged Interface
Is App.ViewModel.Items of type ObservableCollection<T>?
If so, when you modify a property of one of the collection items and raise a property change event (via INotifyPropertyChanged) indicating the collection property that your ListBox.ItemsSource is bound to, the DataTemplate bindings will do the rest.

Resources