Unable to handle MouseDown event from ListView Item (Label) - c#

I have a List View which I am populating with Labels via code. When the user clicks the label I want to handle the MouseDown event, but it doesn't fire. The preview mouse down does fire.
I understand there is something here about routing / bubbling events which I guess is going to the issue I'm hitting, this is a concept I'm yet to grasp.
I cannot use the preview event as this does not contain the object I need (the label information does not get assigned until the second click of the label, so I assume I need the MouseDown and not the preview)
Appreciate your time.
XAML
<telerik:RadTabItem x:Name="Media" Header="Media" Height="22" Width="100">
<Grid x:Name="ListboxMedia">
<ListView x:Name="ListViewImages" HorizontalAlignment="Left" Height="303" Margin="697,10,0,0" VerticalAlignment="Top" Width="178" ScrollViewer.HorizontalScrollBarVisibility="Disabled" ScrollViewer.VerticalScrollBarVisibility="Auto" IsTabStop="True" TabIndex="3" MouseDown="ListViewImages_MouseDown" PreviewMouseDown="ListViewImages_PreviewMouseDown">
<ListView.View>
<GridView>
<GridViewColumn x:Name="ListViewImageColumn" Header="Images" Width="178" />
</GridView>
</ListView.View>
</ListView>
<Button x:Name="BtnUpload" Content="Upload" Height="24" Margin="809,318,38,0" VerticalAlignment="Top" Click="BtnUpload_Click"/>
<Button x:Name="BtnDownload" Content="Download" Height="24" Margin="728,318,109,0" VerticalAlignment="Top"/>
<Image x:Name="ImageViewPort" HorizontalAlignment="Left" Height="293" Margin="21,20,0,0" VerticalAlignment="Top" Width="581"/>
</Grid>
</telerik:RadTabItem>
Method which populates Labels into ListViewImages
void PopulateMedia()
{
var collectImages = new Media().CollectMediaForAsset(_assetId);
int i = 1;
foreach (var collectImage in collectImages)
{
var label = new Label();
label.Tag = collectImage.FileName;
label.Content = "Image" + i.ToString();
ListViewImages.Items.Add(label);
i++;
}
}
Handlers
private void ListViewImages_MouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Debug.WriteLine("Clicked Down"); //does not work
}
private void ListViewImages_PreviewMouseDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Debug.WriteLine("Clicked Preview"); //works
}

Used selection changed event instead

Related

Unable to update binded control in Silverlight view

XAML code:
<TextBlock Text="Country" Foreground="white" TextAlignment="Right" Grid.Row="2" Grid.Column="0" />
<TextBox
x:Name="txtCountries"
Grid.Row="2"
Grid.Column="1"
Grid.ColumnSpan="2"
HorizontalAlignment="Stretch"
Margin="2, 2, 2, 2"
Text="{Binding PhysicalDeliveryParameters.Countries, Converter={StaticResource EnumerableToTextConverter}, ConverterParameter='...'}"
IsReadOnly="True">
</TextBox>
<Button
Grid.Row="2"
Grid.Column="3"
Content="..."
HorizontalAlignment="Left"
Tag="Countries"
Click="ButtonBase_OnClick" />
C# code :
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
PhysicalDeliveryParametersViewModel pvm = GetViewModel();
GenericObservableCollection<SelectableItem> items = pvm.Countries;
PhysicalDeliveryParametersDlg dlg = new PhysicalDeliveryParametersDlg(items);
dlg.Closed += (o, args) =>
{
BindingExpression binding = txtCountries.GetBindingExpression(TextBox.TextProperty);
if(null != binding)
binding.UpdateSource();
};
dlg.ShowDialog();
}
When I click on the button, the ButtonBase_OnClick() method executes : a dialog appears (PhysicalDeliveryParametersDlg class) and I choose some values. The binded data (PhysicalDeliveryParameters.Countries, which is an ObservableCollection) is updated, but not the Text property of my TextBox... Did I do something wrong ?
PS : I'm not sure I use the best method to create a modal window in Silverlight, could you give me some advice ?
It looks like the problem is that PropertyChanged never gets raised on the "Countries" property, so the view doesn't know it needs to update. (Actually, it probably wouldn't help to raise "PropertyChanged" in this case -- since the object reference has not changed, I believe the runtime would ignore it.)
I would just add another property "CountriesString" or similar:
Text="{Binding PhysicalDeliveryParameters.CountriesString}"
Update the property whenever is appropriate:
dlg.Closed += (o, args) =>
{
pvm.CountriesString = string.Join(", ", pvm.Countries);
};

Keyboard overlaps textbox

I'm using a list of textboxes for a registering document in a WP8 app.
The number of textboxes is quite large, so the user has to scroll between them.
To navigate between one field to another, I added two applicationbarIcons, next and previous. Pressing on next will change the focus to the next textbox from list, and scroll the content of the scroll viewer with the height of the textbox (in this case 50).
However, sometimes, when switching the focus to the element bellow, the keyboard covers the text box. (the content doesn't scroll up).
Is there a way to force the textbox to move above the keyboard, even if it is in a scroll view?
<ScrollViewer x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<StackPanel>
<TextBlock Text="{Binding Source={StaticResource LocalizedStrings}, Path=LocalizedResources.STRING_CONTACT}" Margin="10,5" FontWeight="SemiBold" Foreground="#878780"></TextBlock>
<StackPanel Margin="10,5" Height="190" Background="#F4F3F4">
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="firstNameTxt" BorderThickness="0" Background="Transparent" InputScope="PersonalFullName"><TextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="lastNameTxt" BorderThickness="0" Background="Transparent" InputScope="PersonalFullName"></my:DefaultTextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="MobileTxt" BorderThickness="0" InputScope="Number" Background="Transparent" ></TextBox>
<TextBox LostFocus="firstNameTxt_LostFocus_1" GotFocus="firstNameTxt_GotFocus_1" Margin="0,-7" FontSize="23" x:Name="EmailTxt" BorderThickness="0" Background="Transparent">
</StackPanel>
</ScrollViewer>
Code behind:
void left_Click(object sender, EventArgs e)
{
int index = this.controls.IndexOf(currentControl) - 1;
if (index == -1)
{
this.Focus();
return;
}
currentControl = this.controls[index];
ContentPanel.ScrollToVerticalOffset(ContentPanel.VerticalOffset - 50);
currentControl.Focus();
}
This is a common issue on WP8. When a textbox is focused, it will translate Application 's RootVisual to bring it into view. This doesn't work well in some cases (when clipboard is on, or in your case). A workaround is manually translating RootVisual to a desired vertical offset on GotFocus and LostFocus events of TextBox.
private void TranslateRootVisualY(int yNew)
{
var rootFrame = Application.Current.RootVisual as PhoneApplicationFrame;
rootFrame.RenderTransform = new CompositeTransform() {TranslateY = yNew};
}
In your case, you can eliminate the automatic translation and make ScrollViewer scroll to desired offset in GotFocus event:
private void firstNameTxt_GotFocus_1(object sender, RoutedEventArgs e)
{
TranslateRootVisualY(0);
Dispatcher.BeginInvoke(() =>{
double destOffset;
//...calculate destination offset
ContentPanel.ScrollToVerticalOffset(destOffset);
});
}
destOffset can be calculated from sender and other function like GetRectFromCharacterIndex

how to change MediaElement source when ListPicker_SelectionChanged?

I'm trying to bind item from list picker to MediaElement Source when user I have the uri store in ListPickerItem Tag my problem I want to change the bleep.Source when ListPicker_SelectionChanged but my problem how to selected and cast it ?
private void ListPicker_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
{
// TODO: Add event handler implementation here.
bleep.Source = lp_sound.SelectedItem.ToString();
}
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<MediaElement x:Name="bleep" Source="soundFiles\ROAR.wav" AutoPlay="False" Visibility="Collapsed"/>
<Button x:Name="ButtonPlay" Content="play" HorizontalAlignment="Left" Margin="170,404,0,0" VerticalAlignment="Top" Click="ButtonPlay_Click"/>
<toolkit:ListPicker x:Name="lp_sound" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Width="408" SelectionChanged="ListPicker_SelectionChanged">
<toolkit:ListPickerItem x:Name="BestRoar" Content="Sound1" Tag="soundFiles\ROAR.wav" ></toolkit:ListPickerItem>
</toolkit:ListPicker>
</Grid>
You can do this to get results. I assumed that you have used local media file in your listpicker.
private void ListPicker_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e){
ListPickerItem item = lp_sound.SelectedItem as ListPickerItem;
if(item!=null)
bleep.Source = new Uri(Convert.ToString(item.Tag), UriKind.Relative);
}
Hope this will help.

How to make the canvas detect touch input properly in C#?

Basically, I'm trying to make the canvas listen for a touch input (tap) and will increment the number of taps on screen. It isn't working when I touch the screen on my device. I debugged my code and nothing seems out of the ordinary except that the touch is not detected. I checked ZIndex and the canvas is in front of the screen to be touchable. How do I make it work?
XAML:
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Margin="188,10,187,397"/>
<Button Content="Reset" HorizontalAlignment="Stretch" Margin="-18,535,-18,0" VerticalAlignment="Top" Click="Button_Click"/>
<Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>
</Grid>
C#:
int taps = 0; // create var to detect number of times, user touches the screen
// Constructor
public MainPage()
{
InitializeComponent();
}
// method to register the touch as the finger is placed on the screen
private void Canvas_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Canvas c = sender as Canvas;
counter.Text = "TOUCHED!";
}
//method register the touch as the finger is lifting up from the screen
private void Canvas_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
//Canvas c = sender as Canvas;
taps++;
counter.Text = taps.ToString(); //convert var from int to string
}
//method register the touch as the finger leaves the area of the screen
private void Canvas_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
//Canvas c = sender as Canvas;
MessageBox.Show("You left the screen without lifting your finger. That does not count as a tap!", "Caution!", MessageBoxButton.OK);
}
// method to reset the counter to zero when button is pressed and released
private void Button_Click(object sender, RoutedEventArgs e)
{
taps = 0; // reset the count
counter.Text = taps.ToString(); // convert var from int to string
}
I don't know why you want to do it with Canvas - it won't work as you have nothing in this Canvas, so it can't register your click/tap, Canvas is also hard to adjust to screen. I think it can be done simpler way if you want to do it with MouseUp/Down - subscribe directly to Grid containing your elements instead of filling this Grid with additional Canvas:
In XAML:
<Grid x:Name="ContentPanel" Margin="12,0,12,0" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="7*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" VerticalAlignment="Center" Grid.Row="0"/>
<Button Content="Reset" HorizontalAlignment="Stretch" VerticalAlignment="Center" Click="Button_Click" Grid.Row="1"/>
<TextBlock Name="Touched" FontSize="50" HorizontalAlignment="Center" TextWrapping="Wrap" Text="Touched" VerticalAlignment="Center" Visibility="Collapsed" Grid.Row="2"/>
</Grid>
In code behind:
private int taps = 0;
public MainPage()
{
InitializeComponent();
ContentPanel.MouseLeftButtonDown += ContentPanel_MouseLeftButtonDown;
ContentPanel.MouseLeftButtonUp += ContentPanel_MouseLeftButtonUp;
}
private void ContentPanel_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
taps++;
counter.Text = taps.ToString(); //convert var from int to string
Touched.Visibility = Visibility.Collapsed;
}
private void ContentPanel_MouseLeftButtonDown(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
Touched.Visibility = Visibility.Visible;
}
// method to reset the counter to zero when button is pressed and released
private void Button_Click(object sender, RoutedEventArgs e)
{
taps = 0; // reset the count
counter.Text = taps.ToString(); // convert var from int to string
}
As you can see I've subscribed to Grid events (which covers whole screen) - but to make it work I had to set its Background Brush to Transparent, otherwise it will work only if you touch text.
There are many other ways to make your App work, but I hope this will help.
Is there a reason why you don't use the touch-events?
Instead of using MouseLeftButtonDown and MouseLeftButtonUp you should use TouchDown and TouchUp.
Only when you don't handle the touch events or the manipulation events they will be mapped to mouse events. In my experience with touch a single tap also not always gets mapped to MouseLeftButtonDown. As far as I know you could also with mouse events only recoginse one finger. When you want to count more fingers it's necessary to use the TouchDown/TouchUp events.
The problem lies in the overlapping style of the grid
so either make grid rows or define a stackpanel inside the grid, something like this.
<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<stackpanel>
<TextBlock Name="counter" FontSize="150" HorizontalAlignment="Center" TextWrapping="Wrap" Text="0" Margin="0,0,0,0"/>
<Canvas ZIndex="0" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseLeftButtonUp="Canvas_MouseLeftButtonUp" MouseLeave="Canvas_MouseLeave"/>
<Button Content="Reset" HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Top" Click="Button_Click"/>
</stackpanel>
</Grid>
Try and check now.
You should set your Background property. If you don't want any background set it to Transparent:
<Canvas ZIndex="99" Background="Transparent" Name="Canvas" HorizontalAlignment="Center" Height="535" VerticalAlignment="Top" Width="446" Tapped="Canvas_CountMyTaps"/>
(If you want the canvas to be on Top be sure to make it have a greater ZIndex than the other elements that it overlaps)
If not set (the default value is null) the element won't capture any taps/click etc, it will be as if they "fall through".
Also, consider using the Tapped event which is a "higher level" event that will respond to clicks, taps with the finger, stylus, etc.

Tap and hold Listbox Windows Phone

Does anybody know how can I add event whenever I press my listbox it will directly run my code. I need it to change my listbox selected item. This is my xaml:
<ListBox x:Name="ListNabi" SelectionChanged="ListNabi_SelectionChanged" ItemsSource="{Binding}" Tap="ListNabi_Tap" Hold="ListNabi_Hold">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Margin="5,0,5,0">
<!--<Image Source="{Binding ImageSource}" Stretch="None"/>-->
<Grid Width="480" Background="White">
<Image x:Name="listDaun" Source="/Images/Button/Button List.png"
Margin="0,5,5,5" Width="38" HorizontalAlignment="Left"></Image>
<TextBlock x:Name="namaNabi" TextWrapping="NoWrap"
Text="{Binding Name}" FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="36" Foreground="#00ADCE" Margin="40,5,0,5"></TextBlock>
<Rectangle Margin="0,50,0,0" Height="2" Fill="#00ADCE" Width="480"/>
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
And in CS I did like this:
private void ListNabi_Hold(object sender, System.Windows.Input.GestureEventArgs e)
{
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_Tap(object sender, System.Windows.Input.GestureEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
}
MessageBox.Show("tes");
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
}
private void ListNabi_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (ListNabi.SelectedIndex != -1)
{
id = ListNabi.SelectedIndex;
changeColor("#00ADCE", "#FFFFFF", "#FFFFFF", "/Images/Button/Button List1.png");
NavigationService.Navigate(new Uri("/Pages/25_Nabi/DetailPage.xaml?id="
+ ListNabi.SelectedIndex, UriKind.Relative));
ListNabi.SelectedIndex = -1;
}
}
But it will only run my code (in this context changeColor()) whenever I hold my listbox after some time or after I release my finger. Is there any event I can use to start run my code whenever my finger start touch?
For that use the following events: ManipulationStarted, ManipulationDelta and ManipulationCompleted. You will get everything you need from positions to the number of different touch points.
You can do sophisticated things with it like dragging and pinching.

Categories

Resources