We are having an issue with HTC phones and touch on the map control. This works on the Samsung Focus or the LG Optima for example.
On the map we show "territories" by calling:
MapPolygon shape = new MapPolygon();
shape.Locations = lb.Points;
shape.StrokeThickness = 1;
shape.Tag = lb;
shape.Stroke =
new SolidColorBrush(Colors.Black);
shape.Fill = lb.ColorBrush;
shape.Tag = lb;
_touchTerritoryBehavior =
new TouchBehavior(shape);
_touchTerritoryBehavior.Tap +=
new EventHandler(_touchTerritoryBehavior_Tap);
MyLayer.Children.Add(shape);
Where the TouchBehaviour is the same as what's inside the WP7 Training Kit The MyLayer is simply a layer in the map xaml
<my:Map Name="myMap" CredentialsProvider="{Binding CredentialsProvider}" LogoVisibility="Collapsed"
ZoomLevel="{Binding Zoom, Mode=TwoWay}"
Center="{Binding Center, Mode=TwoWay}" AnimationLevel="None"
Height="680" Width="480" VerticalAlignment="Bottom" CopyrightVisibility="Collapsed" ViewChangeEnd="myMap_ViewChangeEnd" Margin="0,55,0,0">
<my:Map.Mode>
<my:RoadMode />
</my:Map.Mode>
<my:MapLayer Name="PinLayer">
</my:MapLayer>
<my:MapLayer x:Name="MyLayer">
<my:MapPolygon Locations="20,-20 20,20 -20,20 -20,-20" Opacity="0.7" />
</my:MapLayer>
So why would this not work on HTC Phones yet work perfectly on other WP7 phones?
Related
I have different elements, controls and views wrapped in frames in order to apply corner radius, which is working fine on Android. But on the iOS side, even though the frame is round cornered, its contents does not clip to its radius but stays square as if nothing is applied.
Sample:-
<Frame BackgroundColor="{DynamicResource Theme}" CornerRadius="15" Padding="0">
<Image Source="{Binding PImage}" HeightRequest="132.5" Aspect="AspectFill"/>
</Frame>
Expected (Which happens in Android):-
Actual:-
How to make the frame contents respect the corner radius like what happens in Android ?
Clip the content of the frame to its boundaries:
<StackLayout Padding="30">
<Frame CornerRadius="30" Padding="0" IsClippedToBounds="True">
<Image Source="https://aka.ms/campus.jpg" />
</Frame>
</StackLayout>
https://stackoverflow.com/a/55611485/1039935
From shared code works in my local site :
The sample solution : Have a check with the version of Visual Studio and Xamarin Forms .Be sure that have updated to the latest version (Visual Studio: 16.6.5, Xamarin Forms : 4.7.0.1239).
Otherwise , you can create a Custom Frame Renderer in iOS to set CornerRadius .
Create a CustomFrame :
public class CustomFrame: Frame
{
}
Create a Custom renderer in iOS:
public class CustomFrameRenderer : FrameRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Frame> e)
{
base.OnElementChanged(e);
Layer.CornerRadius = Element.CornerRadius;
//Layer.CornerRadius = 15;
Layer.MasksToBounds = true;
}
}
In Xaml use the custom Renderer :
<local:CustomFrame BackgroundColor="CadetBlue"
Padding="0">
<Image Source="XamarinLogo.png"
HeightRequest="132.5"
Aspect="AspectFill" />
</local:CustomFrame>
I have a pivot control with non data bound pivot items which have different kind of structure. all of them have simple text headers. How can we change the visibility of the headers
based on orientation changes? what I want to achieve is, when the phone is in landscape i want
the headers to be invisible and all the space to be utilized by the the respective contents inside the pivot items. I tried a lot, and the biggest problem is the panel that carries the headers is always taking the original height.(I tried to change font size, visibility etc...)
Please help. Here is my code sample
<controls:Pivot x:Name="pvtMain" >
<controls:PivotItem x:Name="pvtItemOne" Header="My Header one">
<MyUserControls:UserControlOne/>
</controls:PivotItem>
<controls:PivotItem x:Name="pvtItemTwo" Header="My Header Two">
<MyUserControls:UserControlTwo/>
</controls:PivotItem>
<controls:PivotItem x:Name="pvtItemThree" Header="My Header Three">
<MyUserControls:UserControlThree/>
</controls:PivotItem>
</controls:PivotItem>
I am using Windows phone SDK 7.0 (for backwards compatibility reason)
This may work. Give it a try!!
void MainPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
{
if (e.Orientation == PageOrientation.Landscape || e.Orientation == PageOrientation.LandscapeLeft || e.Orientation == PageOrientation.LandscapeRight)
{
pvtItemOne.Header = null;
pvtItemTwo.Header = null;
pvtItemThree.Header = null;
pvtMain.Margin = new Thickness(0, -150, 0, 0);
}
else
{
pvtItemOne.Header = "My Header One";
pvtItemTwo.Header = "My Header Two";
pvtItemThree.Header = "My Header Three";
pvtMain.Margin = new Thickness(0);
}
}
By the way, you don't need to maintain any backward compatibility for 7.0 devices. Microsoft stopped support for those devices long back and Marketplace is closed for those.
You can do the following :
<controls:PivotItem >
<controls:PivotItem.Header>
<Border x:Name="PivotItemHeader">
<TextBlock Text="Test" />
</Border>
</controls:PivotItem.Header>
<StackPanel>
<TextBlock Text="line1" />
<TextBlock Text="line2" />
</StackPanel>
</controls:PivotItem>
By using the "border" inside the Header you can control its visibility from code.
like : PivotItemHeader.Visibility = System.Windows.Visibility.Collapsed ;
I know it is not pretty but it works.
I want to use a WriteableBitmap to render a programmatically instantiated UserControl to a jpg/png image to use it as a live tile background image in a Windows Phone 7.1 project, but DataBinding is not working as expected when rendering the control.
In general, the UserControl is something like this:
<UserControl>
<Grid x:Name="LayoutRoot" Height="173" Width="173" >
<Grid.Background >
<SolidColorBrush Color="{StaticResource PhoneAccentColor}" />
</Grid.Background >
<Grid.RowDefinitions>
<RowDefinition Height="27"/>
<RowDefinition Height="146"/>
</Grid.RowDefinitions >
<ItemsControl Grid.Row="1" Margin="10,0,0,0" ItemsSource="{Binding}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding MyBindingProperty, FallbackValue=xxx}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock Text="Hello World" FontSize="22" Margin="5,0,0,0"/>
<TextBlock TextWrapping="Wrap" Text="{Binding Count, FallbackValue=-1}" FontSize="18.667" Margin="123,0,0,0"/>
</Grid>
</UserControl>
When I now put this control onto a PhoneApplicationPage and assign a list with items of my data structure to the DataContext property of the UserControl, everything works fine and I see one TextBlock for each list item and the Text property of that TextBlock is correctly displaying the value of the property of my data structure. Also the last TextBlock on the Grid displays correctly the current count of list items.
BUT when I'm now trying to programmatically create that UserControl, assign the same list to the DataContext and then use a WriteableBitmap to render it to an image file, it seems that all DataBindings within the DataTemplate of the ItemsControl aren't working anymore, they're displaying the FallbackValue now. Although the DataBinding of the outer TextBlock in the Grid is still working perfectly and also I got the correct number of TextBlocks in the StackPanel (= items in the bound list).
Here is my code for creating the the WriteableBitmap:
var tile = new MyTileControl { DataContext = this._myList };
tile.Arrange(new Rect(0, 0, 173, 173));
tile.Measure(new Size(173, 173));
var bmp = new WriteableBitmap(173, 173);
bmp.Render(tile, null);
bmp.Invalidate();
What's the problem with the DataBindings in the DataTemplate when rendering through a WriteableBitmap and how can I solve it?
I think, that your control not fully created yet, and you can't grab bitmap just after creation. Try to use Dispatcher.BeginInvoke or something else for delayed grabbing of image.
Also, add this control to your page and look where is a problem - in control creation or in bitmap? This give you more information about a problem.
in my app for WP7(mango) I need to navigate the user from one point to another. I know there is the Map control that lets you draw staff on it, but how do you ask it to draw the path for you? (based on the specified destination & user's current location - but that keeps changing so how do you update the route if he goes of the way?)
To update the map with the users current location, use the GeoCoordinateWatcher and update the position of a databound Pushpin as it changes. Remember to set the minimum distance to something low, like 5 meters.
A pushpin like the one on bing maps, can be created with this XAML template:
<maps:Pushpin Background="{StaticResource PushpinLocationBrush}"
Location="{Binding MyLocation}">
<maps:Pushpin.Template>
<ControlTemplate>
<Grid>
<Rectangle Width="15"
Height="15"
Margin="0"
Fill="Black">
<Rectangle.Projection>
<PlaneProjection CenterOfRotationX="0"
LocalOffsetX="-2"
LocalOffsetY="5"
RotationZ="45" />
</Rectangle.Projection>
</Rectangle>
<Ellipse Width="7"
Height="7"
Margin="0"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Fill="Orange"
RenderTransformOrigin="0.339,0.232"
StrokeThickness="0" />
</Grid>
</ControlTemplate>
</maps:Pushpin.Template>
</maps:Pushpin>
Getting the GeoCoordinate of a address can be done with Bing Maps. You can read more about Bing Services here: http://msdn.microsoft.com/en-us/library/cc980922.aspx -- the one you need is the GeoCodeService
Drawing a path is rather complicated, specially if you want it to follow the roads. For this, you need the Bing Maps Route Service.
Add the service to Visual Studio, with RouteServiceReference as name, and then you can utilize following code to get the path fragments, and add them to your map. The XAML below reflects the controls I add the fragments to:
List<GeoCoordinate> locations = new List<GeoCoordinate>();
RouteServiceClient routeService = new RouteServiceClient("BasicHttpBinding_IRouteService");
routeService.CalculateRouteCompleted += (sender, e) =>
{
var points = e.Result.Result.RoutePath.Points;
var coordinates = points.Select(x => new GeoCoordinate(x.Latitude, x.Longitude));
var routeColor = Colors.Blue;
var routeBrush = new SolidColorBrush(routeColor);
var routeLine = new MapPolyline()
{
Locations = new LocationCollection(),
Stroke = routeBrush,
Opacity = 0.65,
StrokeThickness = 5.0,
};
foreach (var location in points)
{
routeLine.Locations.Add(new GeoCoordinate(location.Latitude, location.Longitude));
}
RouteLayer.Children.Add(routeLine);
};
RouteBingMap.SetView(LocationRect.CreateLocationRect(locations));
routeService.CalculateRouteAsync(new RouteRequest()
{
Credentials = new Credentials()
{
ApplicationId = "YOURBINGMAPSKEYHERE"
},
Options = new RouteOptions()
{
RoutePathType = RoutePathType.Points
},
Waypoints = new ObservableCollection<Waypoint>(
locations.Select(x => new Waypoint()
{
Location = x.Location
}))
});
Related XAML:
<maps:Map x:Name="RouteBingMap"
AnimationLevel="None"
CopyrightVisibility="Collapsed"
CredentialsProvider="YOURBINGMAPSKEYHERE"
LogoVisibility="Collapsed"
ZoomBarVisibility="Collapsed"
ZoomLevel="12">
<maps:MapLayer x:Name="RouteLayer" />
</maps: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;
}