I am currently using Mapsui in my .NET Maui project. I have gotten to the point of building out my callouts and displaying one at a time, but they are anchored to the pins for the locations (seen here):
I was wondering if there was a way to make these callouts "float" (similar to Google Maps implementation shown below):
Is there a way to do this with the callouts, or am I going to need to build another layer and have it visible/hidden based on the ClickEvents?
There are samples available on the github of Mapsui : PinSample.cs
The position of the callout is defined by Callout.Anchor, you can base it on the size of the pin :
pin.Callout.Anchor = new Point(0, pin.Height * pin.Scale);
Oops just see it is not what you asked for, I am currently doing something similar by using another element on top of the map.
XAML :
<Grid VerticalOptions="FillAndExpand">
<mapsui:MapView x:Name="mapView"
VerticalOptions="FillAndExpand"
HorizontalOptions="Fill"/>
<Border
x:Name="mapContext"
IsVisible="false"
Padding="10"
Margin="5"
HorizontalOptions="Center"
VerticalOptions="Start">
<Border.StrokeShape>
<RoundRectangle CornerRadius="10" />
</Border.StrokeShape>
<Label
Text="Some content"
BackgroundColor="White"></Label>
</Border>
</Grid>
You can use the events to close / open it :
public MapTest()
{
InitializeComponent();
mapView.MapClicked += OnMapClicked;
mapView.PinClicked += OnPinClicked;
}
private void OnPinClicked(object sender, PinClickedEventArgs e)
{
mapContext.IsVisible = true;
}
private void OnMapClicked(object sender, MapClickedEventArgs e)
{
mapContext.IsVisible = false;
}
You can also change the content based on the PinClickedEventArgs.Pin.
Related
how to add an icon before the text "Share"?
below code only displays text and not icon. I have added icon into drawable folder
<ContentPage.ToolbarItems>
<ToolbarItem Name="Share" Order="Secondary" IconImageSource="icon_share.png" Icon="icon_share.png" Priority="0" />
<ToolbarItem Name="Delete" Order="Secondary" IconImageSource="icon_delete.png" Icon="icon_delete.png" Priority="1" />
</ContentPage.ToolbarItems>
The icon for Secondary Toolbar item is hidden by design .
Check the threads :
How to change icon of Secondary Toolbaritem Xamarin Forms.
https://forums.xamarin.com/discussion/47989/icon-for-toolbaritem-with-order-secondary.
I create the workaround that mentioned in the links, it works fine .
Xaml
<ContentPage.ToolbarItems>
<ToolbarItem Order="Primary" Icon="dots.png" Priority="1" Clicked="ToolbarItem_Clicked" />
</ContentPage.ToolbarItems>
<RelativeLayout>
<ListView x:Name="SecondaryToolbarListView"
VerticalOptions="Start"
HorizontalOptions="Start"
WidthRequest="150" IsVisible="False"
ItemTapped="SecondaryToolbarListView_ItemTapped"
RelativeLayout.XConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1, Constant=-160}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal" Spacing="10" Padding="5,5,5,5">
<Image HeightRequest="30" HorizontalOptions="Start" VerticalOptions="Center" Source="{Binding ImagePath}" />
<Label FontSize="15" VerticalOptions="Center" HorizontalOptions="Start" Text="{Binding MenuText}"/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</RelativeLayout>
Code behind
public class ToolbarItemModel
{
public string ImagePath { get; set; }
public string MenuText { get; set; }
}
public Page2()
{
InitializeComponent();
var items = new List<ToolbarItemModel>
{
new ToolbarItemModel {ImagePath = "dog.png", MenuText = "First Item"},
new ToolbarItemModel {ImagePath = "dog.png", MenuText = "Second Item"}
};
SecondaryToolbarListView.ItemsSource = items;
}
private void ToolbarItem_Clicked(object sender, EventArgs e)
{
SecondaryToolbarListView.IsVisible = !SecondaryToolbarListView.IsVisible;
}
private void SecondaryToolbarListView_ItemTapped(object sender, ItemTappedEventArgs e)
{
}
The Images aren't appearing because you have incorrectly added icon_share.png and icon_delete.png to your project.
Here is Microsoft's recommendations on how to add images to your Xamarin.Forms project:
Image files can be added to each application project and referenced from Xamarin.Forms shared code. This method of distributing images is required when images are platform-specific, such as when using different resolutions on different platforms, or slightly different designs.
To use a single image across all apps, the same filename must be used on every platform, and it should be a valid Android resource name (i.e. only lowercase letters, numerals, the underscore, and the period are allowed).
iOS - The preferred way to manage and support images since iOS 9 is to use Asset Catalog Image Sets, which should contain all of the versions of an image that are necessary to support various devices and scale factors for an application. For more information, see Adding Images to an Asset Catalog Image Set.
Android - Place images in the Resources/drawable directory with Build Action: AndroidResource. High- and low-DPI versions of an image can also be supplied (in appropriately named Resources subdirectories such as drawable-ldpi, drawable-hdpi, and drawable-xhdpi).
Universal Windows Platform (UWP) - By default, images should be placed in the application's root directory with Build Action: Content. Alternatively, images can be placed in a different directory which is then specified with a platform-specific. For more information, see Default image directory on Windows.
Recommendations
Permanently Remove Icon; Icon was deprecated in favor of IconImageSource
Temporarily remove IconImageSource, replacing it with Text="Share" and Text="Delete":
This will confirm that ContentPage.ToolbarItems is working properly and that you have incorrectly added your png images to the Xamarin.Forms project
<ContentPage.ToolbarItems>
<ToolbarItem Name="Share" Order="Secondary" Text="Share" />
<ToolbarItem Name="Delete" Order="Secondary" Text="Delete" />
</ContentPage.ToolbarItems>
I'm using a Frame in a Window to display content and I added navigation with
<Frame NavigationUIVisibility="Visible" Name="FrameContent" VerticalAlignment="Stretch" Margin="0,34,-0.8,0.4" Grid.RowSpan="2"/>
And in Window.xsml.cs
FrameContent.Navigate(new HomeView());
And the navigation bar looks like this:
Is there any way of changing the default look of this bar? Or is the only option to create a new one?
In my WPF app I created my own, The simplest version of it was like:
<Grid VerticalAlignment="Top" Height="50" Background="DarkGray">
<StackPanel Orientation="Horizontal">
<Button Content="Back" Click="Back_Btn"/>
<Button Content="Next" Click="Next_Btn"/>
</StackPanel>
</Grid>
In code behind:
private void Next_Btn(object sender, RoutedEventArgs e)
{
if (this.NavigationService.CanGoForward)
NavigationService.GoForward();
else
NavigationService.Navigate(new HomeView());
}
private void Back_Btn(object sender, RoutedEventArgs e)
{
if (this.NavigationService.CanGoBack)
NavigationService.GoBack();
else
NavigationService.Navigate(new HomeView());
}
If you want you can design the buttons with materialdesign package from NuGet for example.
The MVVM version of it is more complex.
There is a way to change the default look of the bar.
Have the xaml file with the frame open.
Open the document outline window.
(From the Visual Studio Toolbar: View => Other Windows => Document Outline)
In the Document Outline window right click on the frame to display a context menu.
Select from the context menu: Edit Template => Edit a Copy...
Press OK on the Create Style Resource window.
Change the contents of Window.Resources to your liking.
I am developing a UWP application in which I have several XAML controls(buttons, textblocks, checkboxes, etc). Ideally, The final user of this app should be able to navigate between these controls ONLY USING MOUSE WHEEL(this is a medical device UI in which only a mouse wheel will be available on top of the monitor). Now my question is that how to force this application use mouse wheel as the primary source of navigation between controls?
Some more feedbacks:
1.Right now, when I run my application in visual studio, I just see mouse pointer and of course buttons are sensitive to mouse clicks but in order to initiate an event, I have to hover to that element and click. MOUSE WHEEL IS NOT WORKING by default to navigate and select controls.
2.when I sideload this UWP application on a raspberry pi device and run the application there, the only way to navigate between controls is using an attached keyboard(possible to navigate and select controls using it). AGAIN ATTACHED MOUSE WHEEL IS NOT WORKING HERE.
an example of controls I use in my code is this:
xaml code:
<Button x:Name="button1" Grid.Column="0" Grid.Row="0" Content="Button1" Click="button1_click" />
<Button x:Name="button2" Grid.Column="1" Grid.Row="0" Content="Button2" Click="button2_click" />
<Button x:Name="button3" Grid.Column="2" Grid.Row="0" Content="Button3" Click="button3_click" />
c# code:
private void button1_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
private void button2_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
private void button3_click(object sender, Windows.UI.Xaml.RoutedEventArgs e)
{
//do sth
}
in above code, it is not possible to navigate between three buttons using mouse wheel(both in visual studio and raspberry pi).
AGAIN ATTACHED MOUSE WHEEL IS NOT WORKING HERE.
How did you register the 'MOUSE WHEEL' event in your code? It worked well on my side.
Please see the following code sample:
<StackPanel x:Name="root" >
<Button x:Name="button1" Grid.Column="0" Grid.Row="0" Content="Button1" Click="button1_click" />
<Button x:Name="button2" Grid.Column="1" Grid.Row="0" Content="Button2" Click="button2_click" />
<Button x:Name="button3" Grid.Column="2" Grid.Row="0" Content="Button3" Click="button3_click" />
</StackPanel>
public MainPage()
{
this.InitializeComponent();
Window.Current.CoreWindow.PointerWheelChanged += CoreWindow_PointerWheelChanged;
}
private async void CoreWindow_PointerWheelChanged(Windows.UI.Core.CoreWindow sender, Windows.UI.Core.PointerEventArgs args)
{
Debug.WriteLine(args.CurrentPoint.Properties.MouseWheelDelta);
UIElement element;
if (args.CurrentPoint.Properties.MouseWheelDelta > 0)
{
element = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Up);
if (element == null)
{
element = FocusManager.FindLastFocusableElement(root) as UIElement;
}
var result = await FocusManager.TryFocusAsync(element, FocusState.Keyboard);
Debug.WriteLine((element as Button).Content.ToString() + " focused: " + result.Succeeded);
}
else
{
element = FocusManager.FindNextFocusableElement(FocusNavigationDirection.Down);
if (element == null)
{
element = FocusManager.FindFirstFocusableElement(root) as UIElement;
}
var result = await FocusManager.TryFocusAsync(element, FocusState.Keyboard);
Debug.WriteLine((element as Button).Content.ToString() + " focused: " + result.Succeeded);
}
}
just to give you an idea.
First you should handle tabIndex properties of all of those Items on form and set their order. also whats being triggered with you will move with the tab in your case with mouse wheel gonna be "Focused" or "GotFocus" method. so an event like "GotFocus" will be needed. also you need to handle mouse wheel movements(up or down). you may google about how to override TabIndex property from tab Key to Mouse wheel as you want.
I'm developing an app and I'd like when the user is in Tablet Mode and switches from one app to other to show a black screen when you press "alt + tab" and the opened apps are being shown. I'd like instead of showing the "myTrip" screenshot of the app to show a black screen.
I know for WPF we had ShowInTaskbar = false but nothing like that in Windows 10 Universal App Platform.
I tried so far:
Window.Current.CoreWindow.VisibilityChanged += CoreWindow_VisibilityChanged;
private void Current_VisibilityChanged(object sender, VisibilityChangedEventArgs e)
{
var parentGrid = RootPanel();
parentGrid.Visibility = e.Visible ? Visibility.Visible : Visibility.Collapsed;
}
But the snapshot image of the app is taken before those events are being called. Any idea on how to do it?
Regards.
I don't get why exactly you want to do this, but here it goes.
You'll need to handle the Activated event of the current thread, and than place a control over your content. See the example bellow.
First, the XAML:
<Canvas Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" >
<Canvas x:Name="contetProtector" Canvas.ZIndex="10" Background="Black" Width="1014" Height="758" Visibility="Collapsed"/>
<TextBlock Text="My precious content" FontSize="50" Canvas.Top="50" Canvas.Left="50"/>
<TextBlock Text="Nobody should see it" FontSize="50" Canvas.Top="100" Canvas.Left="50"/>
</Canvas>
Then, the codebehind of the page:
public MainPage()
{
this.InitializeComponent();
CoreWindow.GetForCurrentThread().Activated += CoreWindowOnActivated;
}
private void CoreWindowOnActivated(CoreWindow sender, WindowActivatedEventArgs args)
{
if(args.WindowActivationState == CoreWindowActivationState.Deactivated)
this.contetProtector.Visibility = Visibility.Visible;
else
this.contetProtector.Visibility = Visibility.Collapsed;
}
Here you can see the unprotected/active screen, and here the protected one.
Hope it helps.
I'm very new in WindowsPhone development and at this moment I'm facing a problem that I couldn't find a way to fix. I'm using a LongListSelector to show some information on the device screen and also a Header and a Footer with some static information. Everything looks right, but I can't handle the Click/Tap on the Header and on the Footer (the other items are working properly).
Someone know how to do it? Is there any event that tells my .cs that someone clicked on the footer or on the header view?
Thanks!
Implement ListFooter and ListHeader in your xaml.
Example :
<phone:LongListSelector x:Name="myLongListSelector"
Background="Transparent"
IsGroupingEnabled="True"
HideEmptyGroups="True">
<phone:LongListSelector.ListFooter>
<Grid Height="70" Tap="Grid_Tap">
<TextBlock Text="Texxt" Foreground="White"
VerticalAlignment="Center"
FontWeight="Bold"
FontSize="20"/>
</Grid>
</phone:LongListSelector.ListFooter>
</phone:LongListSelector>
Now in your cs file, you have :
private void Grid_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
}