I have created a Doubletapped event for Grid. That is whenever a Doubletap event is generated on anywhere in the grid a popup should show up. However the popup does not show up if I do double tap on the grid, it shows up if I double tap on the Listview which is part of the grid.
Can anyone please help as to what is wrong here and how can I generated a popup when the user double taps on grid and not just on listview.
<Grid Margin="0" Doubletapped="Grid_on_Doubletapped_1"
<ListView x:Name="ItemListView" \>
<\Grid>
Thanks,
Padamkar
Maybe the grid is not actually as large as you think. Try changing the background to verify.
Hi I am trying with Microsoft Surface its working fine for me .I have written the following code
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}" DoubleTapped="Grid_DoubleTapped_1">
<ListView Background="Beige" Height="400" Width="400">
</ListView>
</Grid>
then in the code behind
private void Grid_DoubleTapped_1(object sender, DoubleTappedRoutedEventArgs e)
{
var msg = new Windows.UI.Popups.MessageDialog("double Tapped");
msg.ShowAsync();
}
I have tried with Microsoft surface,its working fine for double tapped
Related
I have developed an app in which I have more than one page in flipview.
now I want to stop the swipe navigation on touch only. i have used Isenabled property but
This will disable the content of the flipview as well, I just wanted to disable its navigation but allow the user to interact with its content because I have need to drag and drop and also zoom-in and zoom-out with its content.
please help me in solving the problem.
You can try this method by setting the ManipulationMode as TranslateX and put the code below inside your FlipView:
xaml:
<FlipView Width="300" Height="300" Name="MyFlipView">
<FlipViewItem ManipulationMode="TranslateX" ManipulationDelta="FlipViewItem_ManipulationDelta">
<Image Source="Assets/1.jpg" ></Image>
</FlipViewItem>
<FlipViewItem ManipulationMode="TranslateX" ManipulationDelta="FlipViewItem_ManipulationDelta">
<Image Source="Assets/2.jpg" ></Image>
</FlipViewItem>
</FlipView>
code behind:
private void FlipViewItem_ManipulationDelta(object sender, ManipulationDeltaRoutedEventArgs e)
{
if (e.Delta.Translation.X != 0)
{
e.Handled = true;
}
}
In order to disable the swipe navigation of FlipView on touch without affecting the FlipViewItem content, please override the ControlTemplate and change ManipulationMode as None in ItemsPresenter and put the code below inside your FlipView:
<FlipView.Template>
<ControlTemplate>
<ItemsPresenter ManipulationMode="None"></ItemsPresenter>
</ControlTemplate>
</FlipView.Template>
I have tested it and it works OK.
I have a usercontrol with grid as content panel, which loads its content from datatemplate, specified in xaml where usercontrol is used.
I am using this usercontrol widely and everything is fine with standard xaml controls in template.
now I am trying to show some charts in this control with OxyPlot
<DataTemplate x:Key="SomeChart">
<Grid x:Name="oxyGrid" >
<oxy:PlotView x:Name="oxyChart" Model="{Binding model}" />
</Grid>
</DataTemplate>
I initialize data model for the chart in usercontrol_loaded
but the chart will not be shown until I manually call InvalidateMeasure for it.
if I call invalidatemeasure from usercontrol_loaded , it will not help.
if I call invalidatemeasure from any point when chart is on the screen - it helps and chart will shows up.
currently, I found that I can call invalidatemeasure in usercontrol_layoutupdated handler but don't like as it fires too often
and requires code outside of usercontrol.
if I try to handle event layoutupdated inside usercontrol and call invalidatemeasure (for oxychart) from there, I am getting "Layout cycle detected. Layout could not complete."
any ideas about what's wrong and how to fix :)
will be greatly appreciated
thanks in advance
ilya
never hurry to post questions :)
just necessary to call UpdateLayout() in usercontrol after loading template
private void spContentPanel_Loaded(object sender, RoutedEventArgs e)
{
LoadTemplate();
UpdateLayout();
}
where spContentPanel is just Grid for template loading
<Grid Grid.Row="1" Name="spContentPanel" Loaded="spContentPanel_Loaded"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</Grid>
I'm developing a windows phone 8.1 app in XAML and C#. I have a ListView getting its Items from a bound list and displaying them through a DataTemplate. Now, in this DataTemplate there are multiple child elements, and when the user taps on an item in the list, I want to be able to determine what child element he actually touched. Depending on that, the app should either expand a view with more details inside the Item, or navigate to another page.
The ItemClick event handler of the ListView is ListView_ItemClick(object sender, ItemClickEventArgs e), and I thought e.OriginalSource would maybe give me the answer, but this just gave me the clicked ListItem.
I have yet to try if encapsulating the children with buttons and intercepting their click events would work, but I'm happy to try any alternative there might be for this.
I just found the solution myself. I set the ListView to SelectionMode="None" and IsItemClickEnabled="False", and then I added Tapped handlers for the individual child elements. Works just as I wanted.
I've got a TextBlock and an Image in one ListViewItem and have just used the Image_PointerPressed event. Doing that also fires the ItemClick event for the ListView so I disable it first, do the stuff I want, then re-enable the ItemClick event so that still fires when the TextBlock is pressed.
Code behind:
private async void imgDone_PointerPressed(object sender, PointerRoutedEventArgs e)
{
// disable click event so it won't fire as well
lvwCouncils.IsItemClickEnabled = false;
// do stuff
MessageDialog m = new MessageDialog("User Details");
await m.ShowAsync();
// Re-enable the click event
lvwCouncils.IsItemClickEnabled = true;
}
Xaml:
<ListView x:Name="lvwCouncils" ItemClick="lvwCouncils_ItemClicked" IsItemClickEnabled="true" >
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock
Grid.Column="1"
Text="{Binding council_name}"
FontSize="24"
Margin="10,10,30,10"
/>
<Border Height="20" Width="20" Margin="10,10,0,10" >
<Image x:Name="imgDone"
Source="Assets/user_earth.png" Stretch="UniformToFill" PointerPressed="imgDone_PointerPressed"/>
</Border>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Use the SelectionChanged event.
Cast the sender object to ListView type and then retrieve the item from the SelectedItem property.
Similar question here but for a different control :
Get the index of the selected item in longlistselector
I am currently working on my first WPF project and trying to make a ListView scrollable.
At first I thought this could be easily done by simply limiting the ListView's width and height and thus forcing a scrollbar to appear automatically whenever the content exceeds its space. This seemed fine at first but due to the handled PreviewMouseDown event (which enables dragging the list's items) it doesn't work after selecting an item.
Second attempt (using ScrollViewer)
<ScrollViewer>
<ListView ItemsSource="{Binding FileViewModels}"
PreviewMouseDown="ListView_MouseMove"
Height="450" Width="200"/>
</ScrollViewer>
Of course, this resulted in a second scrollbar whenever the list's content became larger than its max height. And dragging the bar still didn't work after selecting an item.
Third (quite foolish) attempt (disabling scrollbar duplicate)
<ScrollViewer>
<ListView ItemsSource="{Binding FileViewModels}"
PreviewMouseDown="ListView_MouseMove"
Height="450" Width="200"
ScrollViewer.VerticalScrollBarVisibility="Disabled"
ScrollViewer.HorizontalScrollBarVisibility="Disabled"/>
</ScrollViewer>
This removed the scrollbar duplicate and enabled scrolling via mouse wheel but disabled the scrollbar, so you couldn't move by clicking and dragging it.
Fourth attempt (constant size of the ScrollViewer)
<ScrollViewer Height="450" Width="200">
<ListView ItemsSource="{Binding FileViewModels}"
PreviewMouseDown="ListView_MouseMove"/>
</ScrollViewer>
Removed the width/height constraint from the ListView and moved it to the ScrollViewer. This enables the scrollbar and removes the duplicate. Unfortunately the mouse wheel doesn't work anymore (dragging the scroll bar works fine).
Could somebody please explain to me why the mouse wheel doesn't work anymore and how to fix this?
Edit
Maybe I should go back to my first solution.
Obviously, the ListView's template already contains a ScrollViewer. The remaining problem would then be that I cannot drag the scrollbar after selecting an item because of the handled PreviewMouseDown event (scrolling via MouseWheel still works in that case). Should I handle the dragging of items differently (it worked fine for me, before wanting to add a scrollbar)? Or is there a way to detect if the cursor is above the scrollbar (so I could then deselect the item which enables scrolling)?
Or are there any other suggestions?
This may help you..
private void ListViewScrollViewer_PreviewMouseWheel(object sender, System.Windows.Input.MouseWheelEventArgs e)
{
ScrollViewer scv = (ScrollViewer)sender;
scv.ScrollToVerticalOffset(scv.VerticalOffset - e.Delta);
e.Handled = true;
}
This would probably be the most comfortable solution:
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter></ItemsPresenter>
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
For me this worked:
<ListView.Template>
<ControlTemplate>
<!-- Empty template to allow ScrollViewer to capture mouse scroll -->
<ItemsPresenter />
</ControlTemplate>
</ListView.Template>
instead of this:
<ListView.Template>
<ControlTemplate>
<ScrollViewer>
<ItemsPresenter></ItemsPresenter>
</ScrollViewer>
</ControlTemplate>
</ListView.Template>
<ScrollViewer Background="Transparent">
If Background is null, the mouse wheel will not work on ScrollViewer. You can set the Background to Transparent or some other value.
In my case this helped:
<ScrollViewer ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Auto" >
<DataGrid x:Name="dataGrid" SelectionMode="Single" ItemsSource="{Binding}" SelectedValuePath="{Binding Item}" AutoGenerateColumns="True">
</DataGrid>
</ScrollViewer>
The design was disabling VerticalScrollBarVisibility attribute in outer scope , i.e. in ScrollViewer.
I want to add some comment to the solution Rocky provided. It worked fine for me, but later I needed to use it in a different window to scroll Grid. I faced a problem: the ScrollViewer did not scroll to the bottom end. The reason was because of attempts to set the invalid VerticalOffset value. The code below works fine for me (just need to change PreviewMouseWheel handler:
private void UIElement_OnPreviewMouseWheel(object sender, MouseWheelEventArgs e)
{
ScrollViewer scroll = (ScrollViewer)sender;
if (e.Delta < 0)
{
if (scroll.VerticalOffset - e.Delta <= scroll.ExtentHeight - scroll.ViewportHeight)
{
scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
}
else
{
scroll.ScrollToBottom();
}
}
else
{
if (scroll.VerticalOffset + e.Delta > 0)
{
scroll.ScrollToVerticalOffset(scroll.VerticalOffset - e.Delta);
}
else
{
scroll.ScrollToTop();
}
}
e.Handled = true;
}
I've been pounding away at this issue for a little while, and have only found part of the solution.
I'm trying to set up a TabControl so that I can in some cases prevent the user from changing the currently selected tab. When the user is prevented from changing the currently selected tab, then they are shown a dialog box.
I have already read the following documents:
WPF - reset ListBox scroll position when ItemsSource changes
http://wizardsofsmart.net/uncategorized/itemssourcechanged-event-using-attached-dependency-properties/
http://joshsmithonwpf.wordpress.com/2009/09/04/how-to-prevent-a-tabitem-from-being-selected/
http://social.expression.microsoft.com/Forums/en-US/wpf/thread/f7b46018-1e97-4bbe-ada8-49b75dbc1da2/
I have implemented the solution indicated in the 3rd link (though all of the above create the same error seen below). And it works, but...
Things mess up thoroughly if the user does the following:
attempts to change the tab when such an action is disallowed. The MessageBox pops up with the error.
the user clicks "OK" and is returned to the original window.
the user tries again to change the tab. No MessageBox appears.
if the user minimizes the window, and then maximizes it again, then the MessageBox that was supposed to appear earlier appears.
the user clicks "OK" and is returned to the original window... but the tab has been changed to the one they selected before, even though they should not be able to change tabs.
This is obviously not ideal behavior. Why isn't the MessageBox appearing the second time, and why is the tab changing when it should be disallowed from doing so?
If I remove the MessageBox part, it works fine.
Here is the code for the TabControl.SelectionChanged event handler:
bool _isChanging = false;
private void tabControlForNavigation_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (!_isChanging && canChangeTabs.IsChecked.HasValue)
{
_isChanging = true;
bool canLeave = canChangeTabs.IsChecked.Value; //normally this would be replaced by a check in the ViewModel
if (!canLeave)
{
int prevIndex = tabControlForNavigation.Items.IndexOf(tabControlForNavigation.SelectedContent);
tabControlForNavigation.SelectedIndex = prevIndex;
MessageBox.Show("Can't change tabs!"); //if I comment out this line, everything works fine.
}
_isChanging = false;
}
}
I am using MVVM to implement this. The Window looks like this:
<Window x:Class="TestTabControlSwitching.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow"
Height="350"
Width="525">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition />
</Grid.RowDefinitions>
<CheckBox x:Name="canChangeTabs"
Content="Can Change Tabs"
IsChecked="True" />
<TabControl x:Name="tabControlForNavigation"
Grid.Row="1"
IsSynchronizedWithCurrentItem="True"
ItemsSource="{Binding Collection}"
SelectedItem="{Binding SelectedItem}"
SelectionChanged="tabControlForNavigation_SelectionChanged"
Margin="4"
HorizontalAlignment="Stretch">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
</TabControl>
</Grid>
I'm omitting the rest of the code for sake of brevity- there is a pretty straight-forward ViewModel structure backing the window.
As you noticed, the problem is the MessageBox inside the event handler. The focus will change to the MessageBox and you can get all kind of undesired effects. I've had my own problems with this.
Here is a couple of SO question on the same subject
WPF: Does MessageBox Break PreviewMouseDown?
Wpf stop routing event when MessageBox appear?
If you must display a message to the user then an alternate approach might be to create a new Window which you style like a MessageBox and then call Show (not ShowDialog) on it inside the event handler.
I know this post is a bit old, but I have a very easy way to accomplish this:
Use the tab_Enter event and create a method that performs your check and displays a MessageBox to the user and then set myTabs.SelectedIndex to the prior index. A simple example:
private void someTab_Enter(object sender, EventArgs e)
{
if (myCondition)
{
MessageBox.Show("Sorry, myCondition will not let you move to this tab.");
myTabs.SelectedIndex = someOtherTabIndex;
}
}
This was a very detailed question. I had the same problem you had (i.e. the message box doesn't display on 2nd or 3rd selection changed until you minimize and maximize the window) and after much debugging and multiple google searches, stumbled on the below linked MSDN forum post.
[TabControl SelectionChanged Strange Behaviour?]
Please ignore the poorly formatted question and answer. But as mentioned in the answer, putting it inside a dispatcher and focussing the selected tab after setting the index resolved the issue for me.
You are missing an easy trick. Just make focusable=False for the Tab header.
<TabItem Header="MY TAB" Focusable="False">
You could bind this property to your view model.
<TabItem Header="MY TAB" Focusable="{Binding Bool_CanHasCheeseBurger}">