Get CommandParameter value from GestureRecognizers in Xamarin froms - c#

I'm sending CommandParameter to TapGestureRecognizer, and it was available in object parameter of my OnTapGestureRecognizerTapped function. But I'm unable to extract value from it. How can I fix this?
My list view (XAML markup):
<ListView x:Name="listViewEvents" RowHeight="120" HasUnevenRows="True">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid Padding="5">
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="90"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" FontSize="Large" Grid.ColumnSpan="2" Text="{Binding UploadTitle}" LineBreakMode="TailTruncation"></Label>
<Label Grid.Row="1" Grid.Column="0" Text="{Binding UploadDescription}" Font="Small" TextColor="Gray" LineBreakMode="TailTruncation"></Label>
<Image Grid.Row="1" Grid.Column="1" Grid.RowSpan="2" Source="{Binding AttachPath}" Aspect="AspectFill">
<Image.GestureRecognizers>
<TapGestureRecognizer
Tapped="OnTapGestureRecognizerTapped"
NumberOfTapsRequired="2"
CommandParameter="{Binding AttachPath_New}"
/>
</Image.GestureRecognizers>
</Image>
<Label Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="2" Text="{Binding FileName}" LineBreakMode="TailTruncation"></Label>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
My C# page :
void OnTapGestureRecognizerTapped(object sender, EventArgs args)
{
string fullPath = "";
Image imageSender = (Image)sender;
if (imageSender.GestureRecognizers.Count > 0)
{
fullPath = imageSender.GestureRecognizers[0].ToString();
}
DownloadFile(imageSender.Source.GetValue(UriImageSource.UriProperty).ToString());
}
Here I'm getting my value:

Another solution you can use is to typecast EventArgs to TappedEventArgs and expose the Parameter.
So to access the CommandParameter you would write the following:
private void OnTapped(object sender, EventArgs e)
{
var te = (TappedEventArgs)e;
string parameter = (string)te.Parameter;
....

You are trying to convert the entire GestureRecognizer to a string, not just its CommandParameter property.
void OnTapGestureRecognizerTapped(object sender, EventArgs args)
{
string fullPath = "";
Image imageSender = (Image)sender;
if (imageSender.GestureRecognizers.Count > 0)
{
var gesture = (TapGestureRecognizer)imageSender.GestureRecognizers[0];
fullPath = (string)gesture.CommandParameter;
}
DownloadFile(imageSender.Source.GetValue(UriImageSource.UriProperty).ToString());
}

Related

Audio transcription with Azure

So I have an audio in WAV format https://youtu.be/nunJDdIlnnk but for some reason, I cannot get it to paste all the transcription in the Textbox, However in the method SpeechRecognizer_Recognizing I can see on my debug windows, that everything is being recognized as the woman speaks.
var config = SpeechConfig.FromSubscription(KEY, Region);
MessageBox.Show("Ready to use speech service in " + config.Region);
// Configure voice
config.SpeechSynthesisVoiceName = "en-US-AriaNeural";
// Configure speech recognition
var taskCompleteionSource = new TaskCompletionSource<int>();
using var audioConfig = AudioConfig.FromWavFileInput(FilePath);
using var speechRecognizer = new SpeechRecognizer(config, audioConfig);
speechRecognizer.Recognizing += SpeechRecognizer_Recognizing;
speechRecognizer.Recognized += SpeechRecognizer_Recognized;
speechRecognizer.SessionStarted += SpeechRecognizer_SessionStarted;
speechRecognizer.SessionStopped += SpeechRecognizer_SessionStopped;
await speechRecognizer.StartContinuousRecognitionAsync().ConfigureAwait(false);
// Waits for completion.
// Use Task.WaitAny to keep the task rooted.
Task.WaitAny(new[] { taskCompleteionSource.Task });
await speechRecognizer.StopContinuousRecognitionAsync().ConfigureAwait(false);
}
private void SpeechRecognizer_SessionStopped(object? sender, SessionEventArgs e)
{
Debug.WriteLine("Stopped");
}
private void SpeechRecognizer_SessionStarted(object? sender, SessionEventArgs e)
{
Debug.WriteLine("Started");
}
private void SpeechRecognizer_Recognized(object? sender, SpeechRecognitionEventArgs e)
{
var transcriptionStringBuilder = new StringBuilder();
if (e.Result.Reason == ResultReason.RecognizedSpeech)
{
transcriptionStringBuilder.Append(e.Result.Text);
Text = transcriptionStringBuilder.ToString(); // This will be the text, that is displayed on textbox
IsVisible = Visibility.Visible;
}
}
private void SpeechRecognizer_Recognizing(object? sender, SpeechRecognitionEventArgs e)
{
Debug.WriteLine("Recogizing: " + e.Result.Text);
}
Output window
This is my XAML code for the UI
<Border Background="#272537"
CornerRadius="20">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="75" />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Text="Transcribe Me"
Foreground="White"
Margin="10,0,0,0"
FontSize="23"
VerticalAlignment="Center" />
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition />
<RowDefinition Height="30" />
</Grid.RowDefinitions>
<syncfusion:SfHubTile Background="#FF1FAEFF">
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Click">
<behaviors:InvokeCommandAction Command="{Binding AzureCommand}"
CommandParameter="Audio" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
<iconPacks:PackIconMaterial Kind="Music" Width="120"
Height="120"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Foreground="White" />
</syncfusion:SfHubTile>
<syncfusion:SfHubTile Grid.Column="1">
<syncfusion:SfHubTile.Header>
<TextBlock Text="Document"
Foreground="White"
FontSize="18"
FontStyle="Oblique" />
</syncfusion:SfHubTile.Header>
<syncfusion:SfHubTile.Title>
<TextBlock Text="Translate"
Foreground="White"
FontSize="18"
HorizontalAlignment="Center"
FontStyle="Oblique" />
</syncfusion:SfHubTile.Title>
<behaviors:Interaction.Triggers>
<behaviors:EventTrigger EventName="Click">
<behaviors:InvokeCommandAction Command="{Binding AzureCommand}"
PassEventArgsToCommand="True"
CommandParameter="Document" />
</behaviors:EventTrigger>
</behaviors:Interaction.Triggers>
</syncfusion:SfHubTile>
<TextBox Grid.Row="1"
IsReadOnly="True"
TextWrapping="Wrap"
Visibility="{Binding IsVisible}"
Text="{Binding Text, UpdateSourceTrigger=PropertyChanged}"
AcceptsReturn="True"
Grid.ColumnSpan="2"
Margin="10" />
<Button Grid.Column="1"
Grid.Row="2"
Visibility="{Binding IsVisible}"
Content="Copy"
Command="{Binding CopyCommand}"
Foreground="White"
FontWeight="Black"
VerticalAlignment="Center"
Margin="0,0,10,10">
</Button>
</Grid>
</Grid>
</Border>
When I run the code, my text box only has the last part of the of the video, witch is "Do I look alright"
The problem was, that I was puttingin my textbox every single sentence that she said.
What you have to do, is to capture everything in the STOPPED method, and probably use a list of chars, loop thru every char, and crate a stringbulder, because using str += item, will create a string every time and is less efficient.

Xamarin - ListView showing all property values but one

I have a Content Page in which I want to show an invoice, for that I have two listviews.
The first one contains the name of the customer, the date and the total cost.
The thing is to get the total cost I have used Shell navigation with parameters and it works fine just not in the listview.
So here is my ViewModel
[QueryProperty(nameof(Total), "total")]
public class InvoiceViewModel : BindableObject
{
string _total;
public string Total
{
get => _total;
set
{
_total = Uri.UnescapeDataString(value ?? string.Empty);
OnPropertyChanged();
}
}
public InvoiceViewModel()
{
_oListOrders = new ObservableCollection<CrOrder>();
GetListCart();
}
private ApiService _apiService = new ApiService();
public List<Invoice> _oListCart = new List<Invoice>();
public ObservableCollection<CrOrder> _oListOrders;
public List<Invoice> ListCart
{
get => _oListCart;
set
{
_oListCart = value;
OnPropertyChanged();
}
}
private async void GetListCart()
{
// call database here
var customerId = Convert.ToInt32(CurrentPropertiesService.GetCustomer());
var customer = await _apiService.GetCustomerById(customerId, CurrentPropertiesService.GetToken());
_oListCart.Add(new Invoice
{
Name = customer.Data.Name,
Date = DateTime.UtcNow,
Total = Convert.ToDecimal(_total),
ListOrders = await GetListOrders()
});
}
private async Task<ObservableCollection<CrOrder>> GetListOrders()
{
// call database here
var cartId = Convert.ToInt32(CurrentPropertiesService.GetCart());
var orders = await _apiService.GetOrdersByCart(cartId, CurrentPropertiesService.GetToken());
ObservableCollection<CrOrder> collection = new ObservableCollection<CrOrder>(orders.Data);
return collection;
}
}
Here is what I have in my View
<ContentPage.Content>
<StackLayout BackgroundColor="#A7A7A7">
<Label Text="{Binding Total}" VerticalOptions="CenterAndExpand" HorizontalOptions="CenterAndExpand"></Label>
<ListView x:Name="ListViewCart" ItemsSource="{Binding ListCart}" HasUnevenRows="True" IsPullToRefreshEnabled="False" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:Invoice">
<ViewCell>
<Frame HasShadow="True" Margin="2" BorderColor="Gray">
<Grid Margin="0" HorizontalOptions="FillAndExpand" VerticalOptions="Center" HeightRequest="150" RowSpacing="0" ColumnSpacing="0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="Nombre del Cliente:" VerticalOptions="Start"/>
<Label Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Name}" VerticalOptions="Start"/>
<Label Grid.Row="1" Grid.Column="0" Text="Fecha Compra:" VerticalOptions="Start"/>
<Label Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Date}" VerticalOptions="Start"/>
<Label Grid.Row="2" Grid.Column="0" Text="Monto Total:" VerticalOptions="Start"/>
<Label Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="2" Text="{Binding Total, StringFormat='{0:N2}€'}" VerticalOptions="Start"/>
<Label Grid.Row="3" Grid.ColumnSpan="3" Text="Detalle Compra" VerticalOptions="Start"/>
<BoxView Grid.Row="4" Grid.ColumnSpan="3" Color="Gray" HeightRequest="2" HorizontalOptions="Fill" />
<Label Grid.Row="5" Grid.Column="0" Text="Nombre" VerticalOptions="Start" TextColor="#9C2424"/>
<Label Grid.Row="5" Grid.Column="1" Text="Monto" VerticalOptions="Start" TextColor="#9C2424"/>
<Label Grid.Row="5" Grid.Column="2" Text="Cantidad" VerticalOptions="Start" TextColor="#9C2424"/>
<StackLayout Grid.Row="6" Grid.ColumnSpan="3" Margin="0" Padding="0">
<ListView x:Name="ListViewOrders" ItemsSource="{Binding ListOrders}" HasUnevenRows="True" IsPullToRefreshEnabled="False" >
<ListView.ItemTemplate>
<DataTemplate x:DataType="model:CrOrder">
<ViewCell IsEnabled="False">
<Grid RowSpacing="0" ColumnSpacing="0" Margin="0" MinimumHeightRequest="50">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Grid.Row="0" Grid.Column="0" Text="{Binding Reference}" TextColor="Black" VerticalOptions="Center" FontSize="12" />
<Label Grid.Row="0" Grid.Column="1" Text="{Binding Price, StringFormat='{0:N2}€'}" TextColor="Black" VerticalOptions="End" FontSize="12" />
<Label Grid.Row="0" Grid.Column="2" Text="{Binding Quantity}" TextColor="Black" VerticalOptions="End" FontSize="12"/>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>...
And on my ContentPage I don't have anything
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class InvoicePage : ContentPage
{
public InvoicePage()
{
InitializeComponent();
//BindingContext = new InvoiceViewModel();
}
}
So on my View I have put a label to check what I thought was happening. So the label shows right the total but when I use the ListView binging it doesn't work I don't know why it is null there.
As you can see the label works fine but where it sais "Monto Total" it shows nothing. Please help I don't know what is going on. Thanks.
EDIT
I tried naming the Total property different and then when I add my Invoice entity to my list I do this
Total = Convert.ToDecimal(TotalCart),
But it isn't working eitherway. I don't know why the first time it returns the value fine but the second it doesn't.
After debbuging I have realized when getting the total property that the first time when GetListCart is being called the value is null and the second time, when the label text is set it returns the correct value. Why is this happening?

Read the text of an Editor inside the DataTemplate

I have a CollectionView with an Editor inside the DataTemplate. Through a button I would like to be able to read the text inside. How can I do?
<CollectionView
x:Name="CollectionEditIcon"
Grid.Row="0"
Grid.ColumnSpan="2"
Margin="10"
HorizontalOptions="Center"
SelectionMode="None">
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="1" VerticalItemSpacing="5" HorizontalItemSpacing="5"/>
</CollectionView.ItemsLayout>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="5"/>
<RowDefinition Height="27"/>
</Grid.RowDefinitions>
<Editor x:Name="EditName" Grid.Column="1" Grid.Row="1" Text="{Binding id}" TextColor="Gray" FontSize="16" MaxLength="40" IsReadOnly="True" IsVisible="{Binding Edit}"/>
<ImageButton Grid.Column="2" Grid.Row="1" BackgroundColor="Transparent" Source="IconEdit.png" Clicked="Edit_Clicked" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
With a button I can make the Editor visible, but then I can't go on
private void Edit_Clicked(object sender, EventArgs e)
{
var button = sender as ImageButton;
var model = button.BindingContext as IconDiary;
model.Edit = true;
}
your Editor is bound to the id property of the model. That means whatever the user enters in the Editor should be reflected in the model automatically
<Editor x:Name="EditName" Grid.Column="1" Grid.Row="1" Text="{Binding id}" TextColor="Gray" FontSize="16" MaxLength="40" IsReadOnly="True" IsVisible="{Binding Edit}"/>
private void Edit_Clicked(object sender, EventArgs e)
{
var button = sender as ImageButton;
var model = button.BindingContext as IconDiary;
model.Edit = true;
// the id property should contain the text the user entered
var text = model.id;
}

UWP C# ListView return the Id value of the clicked row

I am fairly new to coding and I am building a database UI.
What I need to do is click on a row in a listview and get the return of the Id.
Below is the code I have but it gets an 'Exception User-Unhandled System.ArgumentNullException: value cannot be null'.
Any help will be predicated.
UWP Xaml <ListView x:Name="ListItems" IsItemClickEnabled="True" ItemClick="ListItems_ItemClick" Tag="{Binding Id}"
>
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
var id = (sender as ListView).Tag as string;
{
testbox.Text = id;
}
Full List View
<ListView x:Name="ListItems" IsItemClickEnabled="True" ItemClick="ListItems_ItemClick" Tag="{Binding Id}"
>
<ListView.ItemTemplate >
<DataTemplate >
<Border
BorderThickness="0,0,0,0">
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250" />
<ColumnDefinition Width="130" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="200" />
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid.Resources>
<Style TargetType="TextBlock">
<Setter Property="Padding" Value="8,0,0,0" />
</Style>
</Grid.Resources>
<TextBlock
Grid.Column="0"
HorizontalAlignment="Stretch"
Text="{Binding LegalName, Mode=OneWay}" />
<TextBlock
Grid.Column="1"
HorizontalAlignment="Stretch"
Text="{Binding PhoneNumber, Mode=OneWay}" />
<TextBlock
Grid.Column="2"
HorizontalAlignment="Stretch"
Text="{Binding EmailAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="3"
HorizontalAlignment="Stretch"
Text="{Binding HomeAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="4"
HorizontalAlignment="Stretch"
Text="{Binding PostalAddress, Mode=OneWay}" />
<TextBlock
Grid.Column="5"
HorizontalAlignment="Stretch"
Text="{Binding Id, Mode=OneWay}" />
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Here's a very easy approach. Bind the TextChanged event of all the texboxes to a TextChanged event :
XAML
<TextBlock Grid.Column="0" TextChanged="textbox_TextChanged".../>
C#
private string selectedText;
private void textbox_TextChanged(object sender, EventArgs e)
{
selectedtext = (sender as TextBlock).Text
}
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
///use selectedtext string as you want
}
do it Like that
1 - do not bind id to list-view Tag because it is Object.
2 - get your id like that
private void ListItems_ItemClick(object sender, ItemClickEventArgs e)
{
if ((e != null) && (e.Item != null))
{
var selected = (lsv.SelectedItem as yourClassType);
var yorItemID=selected .id;
}
}

Updating Canvas along with Databound properties

I created a class "MyPolygonClass" from which I created an instance that I have databound to the User Control.
This works fine.
However, if the user changes the number of polygon sides I would like to update a canvas, also shown in the User Contol - but not part of MyPolygonClass
I initially run UpdateCanvas(), but it doesn't update if _poly is updated. How do I call UpdateCanvas() everytime _poly is changed?
public partial class MainWindow : Window
{
private MyPolygonClass _poly;
public MainWindow()
{
InitializeComponent();
}
public void UpdateCanvas()
{
//Create a canvas
Canvas drawingCanvas = GenerateCanvas(this._poly.CornerCount);
//Overwrite the existing Canvas
var vb = drawingPlaceholder.Parent as Viewbox;
if (vb != null)
{
vb.Child = drawingCanvas;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
BackgroundWorker worker = new BackgroundWorker();
worker.RunWorkerCompleted += worker_RunWorkerCompleted;
worker.DoWork += worker_DoWork;
worker.RunWorkerAsync();
}
void worker_DoWork(object sender, DoWorkEventArgs e)
{
//Gets the Info from a Database
this._poly = DataSupplier.GetPolygon();
}
void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
//Do Databinding Here
Menu.DataContext = this._poly;
// Display
UpdateCanvas();
}
}
XAML:
<Grid.Resources>
<DataTemplate x:Key="LegTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Viewbox Grid.Row="0" Grid.Column="0" >
<Label Name="IdLabel" Content="{Binding Path=Name}"/>
</Viewbox>
<WrapPanel Grid.Row="0" Grid.Column="3">
<Button FontFamily="Marlett" Name="ButtonUp" Content="5" Click="Button_Click_Move_Leg_Up" Style="{StaticResource LegButtonUp}"></Button>
<Button FontFamily="Marlett" Name="ButtonDown" Content="6" Click="Button_Click_Move_Leg_Down" Style="{StaticResource LegButtonDown}"></Button>
<Button Name="ButtonDelete" Content="x" Click="Button_Click_Delete_Leg" Style="{StaticResource LegButtonDel}"></Button>
</WrapPanel>
<TextBox Grid.Row="0" Grid.Column="1" Name="TextBoxLength" Text="{Binding Path=Length, Converter={StaticResource DoubleConverter}, ConverterCulture=de-de, Mode=TwoWay, StringFormat=N1}" TextAlignment="Right"/>
<TextBox Grid.Row="0" Grid.Column="2" Name="TextBoxAngle" Text="{Binding Path=Angle, Converter={StaticResource DoubleConverter}, ConverterCulture=de-de, Mode=TwoWay, StringFormat=N1}" TextAlignment="Right"/>
</Grid>
</DataTemplate>
XAML2:
<StackPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition Height="5"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="1" HorizontalAlignment="Right">Length</Label>
<Label Grid.Row="0" Grid.Column="2" HorizontalAlignment="Right">Angle</Label>
</Grid>
<ItemsControl x:Name="LbLegs" ItemTemplate="{DynamicResource LegTemplate}" />
<Button Content="AddLeg" Click="Button_Click_2"></Button>

Categories