I work on an app where the user can edit a "big" form:
The form contains a lot of fields: it is displayed in a Pivot, where each PivotItem represents a category of the form.
Some categories contain one or more child items: they are displayed through a Master-Detail presentation.
To display the items of the Detail part, I use a ContentPresenter that is binded directly to the Model:
<ContentPresenter
x:Name="DetailContentPresenter"
Grid.Column="1"
Grid.RowSpan="2"
BorderThickness="1,0,0,0"
Padding="24,0"
BorderBrush="{ThemeResource SystemControlForegroundBaseLowBrush}"
Content="{x:Bind MasterListView.SelectedItem, Mode=OneWay}">
<ContentPresenter.ContentTemplate>
<DataTemplate x:DataType="models:Form_Parts">
<...>
</DataTemplate>
</ContentPresenter.ContentTemplate>
</ContentPresenter>
This works fine, but there is a "third" level in the main form: a list of photos, that I display in the ContentPresenter through a GridView. This works also great, but I would like to use an "Add" button or the "ItemClick" event to interact with the photos: I don't see how I could bind a Command in the main ViewModel, instead of the ContentPresenter's DataContext. The other fields of this form bind well on this ViewModel.
I did some tests without any result:
<StackPanel Orientation="Horizontal" Grid.Row="1">
<GridView ItemsSource="{Binding images}"
ItemClick="{Binding PhotoClickCommand}">
<GridView.ItemTemplate>
<DataTemplate>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Image Stretch="UniformToFill"
Source="{Binding bitmap_image}" />
</Border>
</DataTemplate>
</GridView.ItemTemplate>
</GridView>
<Border BorderBrush="Gray" BorderThickness="1"
Padding="10"
Height="150" Width="190">
<Button Command="{Binding Path=DataContext.AddPhotoCommand, ElementName=DetailsPage}"
Height="100" Width="100">
<Viewbox>
<SymbolIcon Symbol="Add"/>
</Viewbox>
</Button>
</Border>
</StackPanel>
=> is there a way to doing this?
Edit :
I solved my problem for the "Add" button thanks Alteik with:
<Button Command="{Binding ElementName=Root, Path=DataContext.AddPhotoCommand}" Height="100" Width="100">
But I always get a problem with the ItemClick of the GridView. I tried this:
<GridView ItemsSource="{Binding images}"
IsItemClickEnabled="True"
SelectionMode="None">
<i:Interaction.Behaviors>
<core:EventTriggerBehavior EventName="Tapped">
<core:InvokeCommandAction Command="{Binding ElementName=Root, Path=DataContext.EditPhotoCommand}"
CommandParameter="{Binding Mode=OneWay}"/>
</core:EventTriggerBehavior>
</i:Interaction.Behaviors>
<...>
</GridView>
But I don't get the expected parameter in the ViewModel:
private void EditPhoto(object sender)
{
Images sImage = (Images)sender;
if (sImage != null)
{
NavigationService.NavigateTo<CommentImageViewModel>(this, new Object[] { sImage }, true);
}
}
The sender is the current Form_Parts (the DataTemplate of the ContentPresenter), whereas I would get the selected item of my images collection, that is binded to the GridView...
=> Whad could I do to fix this?
You should be able to change the DataContext in a child element doing this:
Command"{Binding ElementName=Root, Path=DataContext.TheCommandFromRoot}"
Obviously you need to set the name of the parent's element to "Root"
I have to add events in Controls which reides in ResourceDictionary ex. List SelectionChanged Image Tap etc, please suggest how cna i do this
Views-> MainPage.XAML
<Grid x:Name="LayoutRoot" Background="{StaticResource AppBackgroundColor}">
<phone:Panorama Name="Container" Grid.Row="0" ItemsSource="{Binding}" SelectionChanged="OnSelectionChanged" toolkit:TiltEffect.IsTiltEnabled="True"
Background="{StaticResource AppBackground}" TitleTemplate="{StaticResource AppPanoramaTitle}">
<phone:PanoramaItem Name="GetGalleryItem" Content="{Binding GetGalleryModel}" ContentTemplate="{StaticResource GetGalleryContent}"/>
</phone:Panorama>
Views->DataTemplates->GetGallery.XAML
<Image Source="{Binding THUMB, Converter = {StaticResource ThumbnailConverter}, ConverterParameter = 120}" Width="120" x:Name="testTap"
Height="120" Stretch="Fill" />
<Image Source="{Binding CategoryImage}" Width="130" Height="130" Stretch="Fill" />
</Grid>
</DataTemplate>
</controls:LongListSelectorEx.ItemTemplate>
</controls:LongListSelectorEx>
</DataTemplate>
For the tap event in your image, you could use the tap key work within your Image tag. such as
Xaml:
<Image Tap="tap_image" Source="{Binding THUMB, Converter = {StaticResource ThumbnailConverter}, ConverterParameter = 120}" Width="120" x:Name="testTap"
Height="120" Stretch="Fill" />
.cs
private void tap_image(object sender, System.Windows.Input.GestureEventArgs e)
{
//do whatever you wanted
}
Yes you could use the SelectionChanged event for a listbox or a longlistselector.
Have a look over here
Hope it helps
I am trying to fire event on tap of listbox item and get the item clicked but the tap event is not firing, please help.
<ListBox Margin="0,40,0,0"
ItemsSource="{Binding Documents}" IsHitTestVisible="True"
Width="450"
VirtualizingStackPanel.VirtualizationMode="Recycling">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<toolkit:WrapPanel Orientation="Horizontal" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Height="150" Margin="5"
Width="150" Background="Aqua">
<TextBlock Text="{Binding Name}" VerticalAlignment="Center" HorizontalAlignment="Center" />
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<commands:MvxEventToCommand Command="{Binding OpenFileCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Are you sure the event never get fired? Maybe you were tapping outside the Grid? Listbox item content (the grid in this case) is not stretcing throughout listbox width, it is aligned left by default. To confirm, try to tap at left most area of listbox item and see if the event fired with that.
Assuming the problem is caused by listbox item content not stretching, you can try to set HorizontalContentAlignment="Stretch" to fix it :
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListBox.ItemContainerStyle>
Default, they look like this: http://wp.qmatteoq.com/wp-content/uploads/2013/01/map.png. I would like to have them look like on Nokia Maps, like this: http://www.themobileindian.com/images/nnews/2012/11/9225/Nokia-Maps.jpg, so they take less space. And everytime I tap on them, they will toggle between icon and description.
Lets say I have two templates for pushpin in resources:
<ControlTemplate x:Key="1" TargetType="maptk:Pushpin">
<Grid x:Name="ContentGrid" Background="Transparent" Margin="-4,0,0,0">
<StackPanel >
<Grid Background="Black">
<StackPanel Margin="5,5,0,0">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand PassEventArgsToCommand="False"
CommandParameter="{Binding}"
Command="{Binding ElementName=NearbyMap, Path=DataContext.Pushpin_OnTapCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBlock Text="{Binding Location}" Foreground="White" />
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LocationName}" Foreground="White" />
<TextBlock Text="-" Foreground="White" Padding="3,0"/>
<TextBlock Text="{Binding LocationName}" Foreground="White" />
</StackPanel>
<TextBlock Text="{Binding LocationName}" Foreground="White" />
<TextBlock Text="{Binding LocationName}" Foreground="White" />
</StackPanel>
</Grid>
<Polygon Fill="Black" Points="0,0 29,0 0,29" Width="29" Height="29" HorizontalAlignment="Left" />
<Grid Height="26" Width="26" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
<Grid.RenderTransform>
<CompositeTransform Rotation="-45"/>
</Grid.RenderTransform>
<Rectangle Fill="Black" HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26" />
<Ellipse HorizontalAlignment="Center" Height="16" Margin="0" VerticalAlignment="Center" Fill="Green" Width="16" />
</Grid>
</StackPanel>
</Grid>
</ControlTemplate>
<ControlTemplate TargetType="maptk:Pushpin" x:Key="2">
<Grid Height="26" Width="26" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" >
<Grid.RenderTransform>
<CompositeTransform Rotation="-45"/>
</Grid.RenderTransform>
<Rectangle Fill="Black" HorizontalAlignment="Center" Margin="0" Stroke="White" VerticalAlignment="Center" Height="26" Width="26"/>
<Ellipse HorizontalAlignment="Center" Height="16" Margin="0" VerticalAlignment="Center" Fill="Red" Width="16"/>
</Grid>
</ControlTemplate>
and the pushpin control:
<maptk:Pushpin x:Name="PushPins" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="{Binding LocationName}" Template="{StaticResource 2}"/>
How can I switch between them with some triggers or something?
#Rares found another solution, that works great in my case...
So the general issue here is just, how to switch/change the design when tapping the pushpin.
Well it seems that when you add the pushpins to the map they get their design from the toolkit, but you still are able to change that by setting the Style propery in code!
So if you hook up each pushpin to a pushpin tap event you can just do the following in your code behind of the XAML page:
private void Pushpin_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
((Pushpin)sender).Style = Application.Current.Resources["PushpinStyle"] as Style;
}
Provided you created a PushpinStyle inside a resourcedictionary that has a Pushpin as TargetType.
To be able to reset the design when pushing on another pushpin, I just keep a reference to the pushpin pressed and reset it's style before changing the style of the newly pressed one!
Works great for me...
You can use a general trick to modify the look of TK components. This can be used for nearly all TK components.
All TK components have styles (defined in XAML), these are not settable via code. But you can override the style in your applicatoin (keep in mind, you override the style in general, so if you modify e.g. pushpin styles, all pushpins inside your app will look like that)
A bit more in detail:
a) Get the TK source from https://phone.codeplex.com/sourcecontrol/latest
b) Have a look into Themes/Generic.xaml
c) Next to the last element, you see the style definition for the pushpin.
Starts with:
<!-- Default Style used for Pushpin -->
<Style TargetType="maptk:Pushpin">
...
d) Copy this style (or you can write it from scratch of course) and modify the style to whatever you like
e) Add this modified code snippet to your Application.Resources (e..g. the Application.Resources section in your App.xaml)
Keep in mind, you also need to reference the right TK namespace.
For pushpin, you need to include:
xmlns:maptk="clr-namespace:Microsoft.Phone.Maps.Toolkit"
Now your app uses the locally overriden style for your pushpin.
Btw: Since TK is Ms-PL licensed, keep in mind that there are probably license restrictions if you take the original source code from MSFT.
I personally found it easier to not use the toolkit for pushpins. Instead I wrote a user control "PushPinUC" that I designed how I wanted it. The UserControl subscribes to the Tap event - so I can expand/retract when it's pressed.
You can add user controls to your Map control using the following code.
private void BindPushpins(IEnumerable<PushpinIVM> pushpins)
{
foreach (var pushpin in pushpins)
{
var pushPinUC = new PushpinUC { Pushpin = pushpin };
var mapOverlay = new MapOverlay { GeoCoordinate = pushpin.Location, Content = pushPinUC };
var mapLayer = new MapLayer { mapOverlay };
Map.Layers.Add(mapLayer);
}
}
I found a solution: add only one control template to the pushpins. The stackpanel is the pushpin with the textbox and the grid before the stackpanel is the pushpin without the textbox. The stackpanel is with visibility collapsed. As you can see there are 2 triggers for the tap event, where i just set the visibility of the pushpin with the textbox to visible or collapsed. You can use any image for the pushpins.
<ctrls:BaseUserControl.Resources>
<ControlTemplate x:Key="PushPinTemplate" TargetType="maptk:Pushpin">
<Grid x:Name="ContentGrid" Background="Transparent" Margin="-4,0,0,0">
<Grid Height="40" Width="30" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" >
<Image Source="/Assets/Images/push1.png" Width="40" Height="40">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command="{Binding ElementName=NearbyMap, Path=DataContext.Rectangle_OnTapCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
<StackPanel x:Name="DetailsPanel" Visibility="{Binding Path=Visibility}">
<Grid x:Name="TestGrid" Background="Black">
<StackPanel Margin="5,5,0,0">
<!--TextBlock tap-->
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command="{Binding ElementName=NearbyMap, Path=DataContext.Pushpin_OnTapCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<TextBlock Text="{Binding LocationName}" Foreground="White" FontSize="25"/>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding StreetName}" Foreground="White" />
<TextBlock Text="{Binding StreetNumber}" Foreground="White" />
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding DistanceToDisplay}" Foreground="White" />
</StackPanel>
</StackPanel>
</Grid>
<Polygon Fill="Black" Points="0,0 29,0 0,29" Width="29" Height="29" HorizontalAlignment="Left" Visibility="Visible"/>
<Grid Height="40" Width="30" Margin="-13,-13,0,0" RenderTransformOrigin="0.5,0.5" HorizontalAlignment="Left">
<Image Source="/Assets/Images/push2.png" Width="40" Height="40">
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command="{Binding ElementName=NearbyMap, Path=DataContext.Rectangle_OnTapCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Image>
</Grid>
</StackPanel>
</Grid>
</ControlTemplate>
</ctrls:BaseUserControl.Resources>
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<maps:Map x:Name="NearbyMap"
Center="{Binding MapCenter, Mode=TwoWay}"
ZoomLevel="15"
dp:MapPushPinDependency.ItemsSource="{Binding Path=Locations, Mode=OneWay}"
>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Tap">
<cmd:EventToCommand PassEventArgsToCommand="True"
Command="{Binding ElementName=NearbyMap, Path=DataContext.Map_OnTapCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<maptk:MapExtensions.Children>
<maptk:MapItemsControl Name="StoresMapItemsControl">
<maptk:MapItemsControl.ItemTemplate>
<DataTemplate>
<maptk:Pushpin x:Name="PushPins" GeoCoordinate="{Binding Location}" Visibility="Visible" Content="{Binding LocationName}" Template="{StaticResource PushPinTemplate}"/>
</DataTemplate>
</maptk:MapItemsControl.ItemTemplate>
</maptk:MapItemsControl>
<maptk:UserLocationMarker x:Name="UserLocationMarker" Visibility="Visible" GeoCoordinate="{Binding MyLocation}"/>
</maptk:MapExtensions.Children>
</maps:Map>
</Grid>
#Depechie
private void RectangleTapAction(GestureEventArgs e)
{
var pushpinControl = TryFindParent<Pushpin>(e.OriginalSource as UIElement);
var pushpin = (pushpinControl as FrameworkElement).DataContext as PushPinModel;
Locations.Where(t => t.Id != pushpin.Id).ToList().ForEach(t => t.Visibility = Visibility.Collapsed);
pushpin.Visibility = pushpin.Visibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible;
e.Handled = true;
}
Locations is an ObservableCollection and there is a Linq where I hide the textbox for other pushpins. PushPinModel has an attribute representing the visibility.
I want to use my surfaceslider control inside tagvisualization so that it responds to finger touch when an object is placed, but when I run the program it doesnt moves at all. Can anybody give me pointers (I am new to this sdk).
<s:TagVisualization x:Class="ControlsBox.TagVisual"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="http://schemas.microsoft.com/surface/2008"
Loaded="TagVisual_Loaded">
<Grid>
<!--ProgressBar Margin="50" HorizontalAlignment="Center" Value=""-->
<TextBlock Height="23" HorizontalAlignment="Center" Margin="0" Name="textBlock1" Text="" VerticalAlignment="Top" Padding="0,6,0,0" Foreground="#FFAA4A4A" />
<s:SurfaceSlider Width="100" Height="20" HorizontalAlignment="Center" VerticalAlignment="Top" Padding="0,50,0,0" Value="60" IsSelectionRangeEnabled="False" Margin="20" Name="mySlider" Maximum="100" Interval="1" ValueChanged="mySlider_ValueChanged">
<s:SurfaceSlider.Effect>
<BlurEffect Radius="2"/>
</s:SurfaceSlider.Effect>
</s:SurfaceSlider>
<Ellipse Width="200" Height="200" Stroke="White" StrokeThickness="8" Opacity="0.7">
<Ellipse.Effect>
<BlurEffect Radius="12" />
</Ellipse.Effect>
</Ellipse>
<Ellipse Height="196" Width="196" Stroke="AntiqueWhite" StrokeThickness="4" >
<Ellipse.Effect>
<BlurEffect Radius="4"/>
</Ellipse.Effect>
</Ellipse>
<Label Content="John's Phone" HorizontalContentAlignment="Center" Padding="0,150,0,0" VerticalContentAlignment="Bottom">
<Label.Effect>
<DropShadowEffect BlurRadius="9" ShadowDepth="0" Color="Aqua"/>
</Label.Effect>
</Label>
</Grid>
private void mySlider_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
{
this.textBlock1.Text = Math.Round(this.mySlider.Value/100,2).ToString();
}
The label is covering it up so the touch doesn't get to it. Set IsHitTestVisible=false on the label and anything else you don't want to receive touch input. Mouse input works the same way. Tools like "Snoop" are great for debugging issues like this