MVVM Light - how to fire command from code behind - windows-phone-7

I need to fire command from WP7 applicationbar. Unfortunately it is not possible, but Laurent published interesting workaround:
private void ApplicationBarMenuItemClick(object sender, System.EventArgs e)
{
var vm = DataContext as MainViewModel;
if (vm != null)
vm.MyCommand.Execute(null);
}
Unfortunately my code behind does not see MainViewModel class or actually any ViewModel class at all! Data binding works well so ViewModel is working fine. What am I doing wrong?

Put a breakpoint on that line of code and check what the value of DataContext is when the breakpoint is hit. If it's null you've probably forgotten to set the data context in your view.
If the DataContext isn't null, make sure it's of type MainViewModel or else the line calling vm.MyCommand.Execute(null) won't ever be called.
Based on the code you pasted, your view should look something like this.
<phone:PhoneApplicationPage x:Class="MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="480" d:DesignHeight="768"
shell:SystemTray.IsVisible="True"
DataContext="{Binding Path=Main, Source={StaticResource Locator}}"
>
<Grid x:Name="LayoutRoot" Background="Transparent">
<!-- the rest has been ommitted for simplicity -->
</Grid>
<phone:PhoneApplicationPage.ApplicationBar>
<shell:ApplicationBar IsVisible="True" IsMenuEnabled="True">
<shell:ApplicationBar.MenuItems>
<shell:ApplicationBarMenuItem x:Name="appBarMenuItem1" Click="ApplicationBarMenuItemClick" Text="Menu Item 1" />
</shell:ApplicationBar.MenuItems>
</shell:ApplicationBar>
</phone:PhoneApplicationPage.ApplicationBar>
</phone:PhoneApplicationPage>
This assumes your ViewModelLocator has the property Main of type MainViewModel.

Related

Silverlight Toolkit 5 Themes does not work

I've got the Problem, that Toolkits Themes just don't wanna apply.
I've installed Silverlight RC 5, Toolkit 5 and are running in Visual Studio 2010 with a Project in Silverlight 3(doesnt offered me Silverlight 4 or higher though).
Well, I read a thousands of Tutorials but I cannot see my mistake.
I am able to use those Controls of the Toolkit properly, but the Theme...just won't apply.
Here's the code:
<UserControl x:Class="Wissensmanagement.Controls.PCategory"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"
xmlns:theming="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.Toolkit"
xmlns:dark="clr-namespace:System.Windows.Controls.Theming;assembly=System.Windows.Controls.Theming.ExpressionDark"
mc:Ignorable="d"
d:DesignHeight="50" d:DesignWidth="625">
<Grid x:Name="LayoutRoot">
<dark:ExpressionDarkTheme>
<StackPanel HorizontalAlignment="Left">
<Button Width="60" Height="30" x:Name="btnLoad" HorizontalAlignment="Left" Content="Test" />
<controlsToolkit:Expander Header="test"/>
</StackPanel>
</dark:ExpressionDarkTheme>
</Grid>
And here is, what I See:
http://imageshack.us/photo/my-images/207/94160286.png/
If there were any hints, I would be appreciated =/
Please Check this link http://www.c-sharpcorner.com/UploadFile/mamta_m/working-with-themes-in-silverlight-toolkit-C-Sharp-based/
It will provide you some help
public Page()
{
InitializeComponent();
Loaded += new RoutedEventHandler(Page_Loaded);
}
void Page_Loaded(object sender, RoutedEventArgs e)
{
Uri uri = new Uri(#"ThemeDemo;component/Microsoft.Windows.Controls.Theming.RainierOrange.xaml", UriKind.Relative);
ImplicitStyleManager.SetResourceDictionaryUri(LayoutRoot, uri);
ImplicitStyleManager.SetApplyMode(LayoutRoot, ImplicitStylesApplyMode.Auto);
ImplicitStyleManager.Apply(LayoutRoot);
}
I hope it helps

Handling tap on Pushpin in a fixed Map

I have a Map control showing a few Pushpins. I do not want the user to navigate in the map so I disable it. But I do want the user to be able to tap on a Pushpin (and in the event I navigate to a detail page).
However when the Map.IsEnabled is false, the Pushpins don't seem to receive any gestures either. I've also tried using IsHitTestVisible, but with no luck.
Some code showing what I'm trying to do. Does anyone have any ideas?
<maps:Map Name="Map"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" ScaleVisibility="Collapsed" ZoomBarVisibility="Collapsed"
IsEnabled="False">
<maps:MapItemsControl ItemsSource="{Binding TheCollection}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Name="Pin" Location="{Binding Coordinate}" Content="{Binding Ix}">
<maps:Pushpin.Background>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
</maps:Pushpin.Background>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="PinTap" />
</toolkit:GestureService.GestureListener>
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
Setting IsEnabled to false prevents the Map control from responding to user input, which affects the child Pushpin as you've seen. If you want the map to be read-only but the Pushpin to respond to gestures then I think you have two options:
Handle all the gesture events on the Map control and set e.Handled to true, which will prevent the Map itself from processing the event, but should leave the PushPin free to handle the tap gesture.
Create a WriteableBitmap of the Map and show that instead, and then display the Pushpin on top (NOTE: I suspect that the Pushpin control won't work outside of the Map control, so you'd need to create/re-template a control to look like a Pushpin).
UPDATE: The events that you need to handle on the Map to make it appear "read-only" but remain enabled are MapPan and MapZoom.
So here's how I solved it after a lot of testing and browsing MSDN. It turns out that things are a bit different in the Map control on Windows Phone (see MSDN). There are new behaviors and events compared to normal Silverlight.
<maps:Map Name="Map"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
CopyrightVisibility="Collapsed" LogoVisibility="Collapsed" ScaleVisibility="Collapsed" ZoomBarVisibility="Collapsed"
MapZoom="Map_MapZoom" MapPan="Map_MapPan">
<maps:MapItemsControl ItemsSource="{Binding TheCollection}">
<maps:MapItemsControl.ItemTemplate>
<DataTemplate>
<maps:Pushpin Name="Pin" Location="{Binding Coordinate}" Content="{Binding Ix}">
<maps:Pushpin.Background>
<SolidColorBrush Color="{StaticResource PhoneAccentColor}"/>
</maps:Pushpin.Background>
<toolkit:GestureService.GestureListener>
<toolkit:GestureListener Tap="PinTap" />
</toolkit:GestureService.GestureListener>
</maps:Pushpin>
</DataTemplate>
</maps:MapItemsControl.ItemTemplate>
</maps:MapItemsControl>
</maps:Map>
...
private void Map_MapPan(object sender, MapDragEventArgs e)
{
e.Handled = true;
}
private void Map_MapZoom(object sender, MapZoomEventArgs e)
{
e.Handled = true;
}

Is it possible to access an external class' member variable in page.xaml.cs?

I'm developing a Windows Phone 7 app, and I have two xaml pages. From the first one, I embed two app bar links to select an image from gallery or capture an image using the camera. I would like the image chosen on the first page to be displayed on a second page, with the app bar buttons showing a confirm yes or no. As of now, I have an image control on the first page (barcodeImage) that gets updated with the choice.
MainPage.xaml
<controls:PanoramaItem Header="welcome">
<ScrollViewer Name="sv1" VerticalScrollBarVisibility="Auto">
<StackPanel Height="1100">
<TextBlock TextWrapping="Wrap">Random text here.
</TextBlock>
<Grid x:Name="Grid2" Grid.Row="1" Margin="12,0,12,0">
<Image Height="150" Margin="28,30,168,0" Name="barcodeImage" Stretch="Fill" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" />
</Grid>
</StackPanel>
</ScrollViewer>
</controls:PanoramaItem>
MainPage.xaml.cs
void cameraCaptureTask_Completed(object sender, PhotoResult e)
{
if (e.TaskResult == TaskResult.OK)
{
BitmapImage bmp = new BitmapImage();
bmp.SetSource(e.ChosenPhoto);
barcodeImage.Source = bmp;
}
}
Confirm.xaml
<!--ContentPanel - place additional content here-->
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<Image Margin="64,36,57,100" x:Name="barcodeImageFinal" Stretch="Fill" />
</Grid>
I'd like barcodeImageFinal to display the final bitmap. How can I make this work? Thanks for looking :)
As I understand your question, you want to create a bitmap in a member of MainPage and then access it from Confirm. One approach would be to create a public static property of some class for your bitmap. For example, maybe create public static BitmapImage FinalBitmap in your App. Then you could set the value of the property in your cameraCaptureTask_Completed and then create a Loaded handler in your Confirm class that sets image source to the stored bitmap.
I think the answer to your question title is yes if you make the member static, although the other class isn't really "external". A normal class member won't be accessible because you don't have an instance of that class.

Pushpin with EventToCommand

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

WPF4: How do you set a value in a UserControl from the Main Window?

This has to be simple, at least it was in good old .Net where it took maybe four lines of code. I'm working in VS2010, C#, WPF4.
I have a user control with a textbox. When I click a button in the main window, I want my user control textbox to reflect some text. Is this possible in WPF4 with less than 500 lines of esoteric code?
The problem is that while I know the textbox is getting the new text as evidenced from breakpoints in the user control code, that text is never being reflected to the main window. The main window still shows the original text. It has to be some kind of binding thing, and I really don't think I should have to create templates and resources and all for this simple situation. It's got to be something simple that I'm forgetting in the forest of WPF4. Below is what I have. After clicking the button, the textbox is still blank; it does not say "hello earthlings."
In the user control code:
public partial class UserControl1 : UserControl
{
public static readonly DependencyProperty TextProperty;
public UserControl1()
{
InitializeComponent();
}
static UserControl1()
{
TextProperty = DependencyProperty.Register("Text", typeof(string), typeof(UserControl1), new UIPropertyMetadata(null));
}
public string Text
{
get { return (string)GetValue(TextProperty); }
set { SetValue(TextProperty, value); }
}
}
User control xaml:
<UserControl x:Class="WTFUserControlLibrary.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Height="164" Width="220">
<TextBox Name="txtTest" BorderBrush="red" BorderThickness="2" Height="25" Text="{Binding ElementName=UserControl1, Path=Text, Mode=TwoWay}"></TextBox>
</Grid>
(I have no idea what the text binding is supposed to be doing in this case.)
Main window code:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void button1_Click(object sender, RoutedEventArgs e)
{
WTFUserControlLibrary.UserControl1 uc = new WTFUserControlLibrary.UserControl1();
uc.Text = "hello earthlings";
}
}
and the main window xaml:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:my="clr-namespace:WTFUserControlLibrary;assembly=WTFUserControlLibrary"
Title="MainWindow" Height="350" Width="525">
<Grid>
<Button Content="Button" Height="23" HorizontalAlignment="Left" Margin="71,65,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" />
<my:UserControl1 HorizontalAlignment="Left" Margin="71,94,0,0" Name="userControl11" VerticalAlignment="Top" Height="116" Width="244" />
</Grid>
Thanks Earthlings (and also those who designed this mess!)
In your method button1_Click you are creating a new user control. This is not the usercontrol in the window and is never displayed.
Instead, give your usercontrol a name in the XAML:
x:Name="uc"
Then in the button1_Click method you just remove that first line where you create a new usercontrol.
update
You want the user control XAML to look more like this:
<UserControl x:Class="WTFUserControlLibrary.UserControl1"
x:Name="thisControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006">
<Grid Height="164" Width="220">
<TextBox Name="txtTest" BorderBrush="red"
BorderThickness="2" Height="25"
Text="{Binding ElementName=thisControl, Path=Text, Mode=TwoWay}" />
</Grid>
I added x:Name="thisControl" to the root UserControl element, and then referenced this in the binding.
I'll try to explain the binding:
You have this textbox inside your user control, but you want to be able to bind the text value to something outside the user control. What you've done is set up a dependency property on the user control, and bound that textbox to it, so you are using the binding infrastructure pass values from the top level of the UserControl to constituent controls inside it.
Basically, it looks like this:
data
---> bind UserControl1.Text to data
---> bind TextBox.Text to UserControl1.Text

Resources