Custom CommandBar to PickerFlyout - xaml

By default PickerFlyout has commandbar that has done and cancel buttons. Is it possible to disable done button programmatically? If not is there any way to add custom command bar and replace default one?
With the help of the answer given i tried to write custom picker from PickerFlyoutBase. But now i'm not able to add content to flyout in xaml. Giving me error saying custompicker doesnt support direct content
<Button>
<Button.Flyout>
<local:custompicker>
<TextBlock Margin="20" FontSize="30" Text="MyPickerFlyout Test" />
</local:custompicker>
</Button.Flyout>
</Button
public class custompicker:PickerFlyoutBase
{
private AppBar OriginalAppBar;
private CommandBar MyCommandBar;
private Page CurrentPage;
public custompicker()
{
var cancelButton = new AppBarButton();
cancelButton.Icon = new SymbolIcon(Symbol.Cancel);
cancelButton.Label = "Cancel";
cancelButton.Click += (s, e) =>
{
this.Hide();
};
MyCommandBar = new CommandBar();
MyCommandBar.PrimaryCommands.Add(cancelButton);
this.Closed += MyPickerFlyout_Closed;
this.Opening += MyPickerFlyout_Opening;
this.Placement = Windows.UI.Xaml.Controls.Primitives.FlyoutPlacementMode.Full;
}
private void MyPickerFlyout_Opening(object sender, object e)
{
CurrentPage = (Windows.UI.Xaml.Window.Current.Content as Frame).Content as Page;
if (CurrentPage != null)
{
OriginalAppBar = CurrentPage.BottomAppBar;
CurrentPage.BottomAppBar = MyCommandBar;
}
}
private void MyPickerFlyout_Closed(object sender, object e)
{
if (CurrentPage != null)
{
CurrentPage.BottomAppBar = OriginalAppBar;
}
}
}

PickerFlyout class has a ConfirmationButtonsVisible property, we can use this property to disable both "Done" and "Cancel" button.
But there is no way to disable only "Done" button. We have to implement a custom "PickerFlyout". Following is a simple custom "PickerFlyout" based on Flyout, you can refer to it to implement your own.
public class MyPickerFlyout : Flyout
{
private AppBar OriginalAppBar;
private CommandBar MyCommandBar;
private Page CurrentPage;
public MyPickerFlyout()
{
var cancelButton = new AppBarButton();
cancelButton.Icon = new SymbolIcon(Symbol.Cancel);
cancelButton.Label = "Cancel";
cancelButton.Click += (s, e) =>
{
this.Hide();
};
MyCommandBar = new CommandBar();
MyCommandBar.PrimaryCommands.Add(cancelButton);
this.Closed += MyPickerFlyout_Closed;
this.Opening += MyPickerFlyout_Opening;
this.Placement = Windows.UI.Xaml.Controls.Primitives.FlyoutPlacementMode.Full;
}
private void MyPickerFlyout_Opening(object sender, object e)
{
CurrentPage = (Windows.UI.Xaml.Window.Current.Content as Frame)?.Content as Page;
if (CurrentPage != null)
{
OriginalAppBar = CurrentPage.BottomAppBar;
CurrentPage.BottomAppBar = MyCommandBar;
}
}
private void MyPickerFlyout_Closed(object sender, object e)
{
if (CurrentPage != null)
{
CurrentPage.BottomAppBar = OriginalAppBar;
}
}
}
Then you can use it in XAML like:
<Button Content="Show Picker">
<Button.Flyout>
<local:MyPickerFlyout Closed="PickerFlyout_Closed">
<TextBlock Margin="20" FontSize="30" Text="MyPickerFlyout Test" />
</local:MyPickerFlyout>
</Button.Flyout>
</Button>
And it looks like:

Related

how to convert WebView into IRandomAccessStream in UWP?

What i have Tried is?
My Xaml code :
<Grid x:Name="MyGrid">
<Button x:Name="but" Content="Click" Click="but_Click"></Button>
</Grid>
My C# code:
private async void but_Click(object sender, RoutedEventArgs e)
{
WebView x = new WebView();
x.Width = 100; x.Height = 100;
InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
await x.CapturePreviewToStreamAsync(ms);
}
when I try to convert Webview to Stream.It throws an error like this.
I don't why this was happening .Can Anyone suggest me , How to convert webview to IRandomAccessstream?
The problem is the WebView has not rendered into xaml visual tree. we need to insert WebView into Page content before calling CapturePreviewToStreamAsync method.
private WebView x;
public MainPage()
{
this.InitializeComponent();
x = new WebView();
x.Height = 100; x.Width = 100;
RootGrid.Children.Add(x);
}
private async void bookmarkBtn_Click(object sender, RoutedEventArgs e)
{
InMemoryRandomAccessStream ms = new InMemoryRandomAccessStream();
await x.CapturePreviewToStreamAsync(ms);
}

Trying to stop SpeechSynthesizer in uwp on click of a button

I'm trying to stop SpeechSynthesizer in uwp on click of a button and also trying to start SpeechSynthesizer on clicking same icon again.Any Help would be appreciated for resolution of this issue.
XAML
<Image x:Name="Sound" Source="ABCD/sound_active.png"
RelativePanel.AlignBottomWithPanel="True"
RelativePanel.RightOf="Pause" Tapped="SoundTap"
Margin="17,0,0,0"
Width="40" Height="40"/>
C# code
private void SoundTap(object sender, TappedRoutedEventArgs e)
{
if ((Sound.Source as BitmapImage).UriSource == new Uri("ms-appx:///ABCD/Sound_active.png", UriKind.Absolute))
{
Sound.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Sound_mute.png"));
textToSpeech.Stop();
}
else
{
Sound.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Sound_active.png"));
textToSpeech.Play();
}
}
public async void Prevevent(object sender, TappedRoutedEventArgs e)
{
currentIndex--;
if (currentIndex < 0)
{
currentIndex = 0;
return;
}
Alph_cap.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Cap_alpha/Cap_" + currentIndex + ".png"));
Alph_small.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Cap_alpha/Sml_" + currentIndex + ".png"));
CapAlphaName.Text = CapsAlpha[currentIndex];
SmallAlphaName.Text = SmallAlpha[currentIndex];
var speechText = this.CapAlphaName.Text;
if (speechText != "")
{
var synth = new SpeechSynthesizer();
var speechStream =await synth.SynthesizeTextToStreamAsync(speechText);
this.textToSpeech.AutoPlay = true;
this.textToSpeech.SetSource(speechStream, speechStream.ContentType);
this.textToSpeech.Play();
}
}
Understanding the question:
Basically you're looking for a toggle switch to turn on and turn off the speech synthesis tts(Text to Speech) in simpler terms.
The Solution:
This couldn't have been simpler enough, never the less, this is how you do it.
Create a Bool property, eg: private IsTTSEnabled = false we'll use this as a flag.
On your Image tap or click, check the current value of IsTTSEnabled and flip it (false if true or true if false) eg: IsTTSEnable = !IsTTSEnable;
Now put a if loop for handling if the TTS is turned on or if it's turned off. Also, since TTS is done using a media element, you don't need to reInitialize your TTS, simple pause and play your media element or start and Stop it as per needs.
So your c# code becomes:
private bool IsTTSEnabled = false;
private void SoundTap(object sender, TappedRoutedEventArgs e)
{
IsTTSEnabled = !IsTTSEnabled;
if(IsTTSEnabled)
{
Sound.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Sound_mute.png"));
textToSpeech.Stop();
}
else
{
Sound.Source = new BitmapImage(new Uri("ms-appx:///ABCD/Sound_active.png"));
textToSpeech.Play();
}
}
Note: This functionality can be easily implemented using Data Binding to provide scalability and ease of management but then the simpler way to do so is like the one I've illustrated

Adding MenuFlyout to a RichEditBox UWP

Is it possible to add a menu flyout to a RichEditBox in UWP in addition to already available flyout items. But i see that there is no flyout property in richeditbox. So is it possible to add one? If Yes please provide the steps to add a menuFlyout. Thanks in advance!
Ofcourse its possible.
<RichEditBox GotFocus="RichEditBox_GotFocus">
<FlyoutBase.AttachedFlyout>
<Flyout>
<Button Content="test"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
</RichEditBox>
private void RichEditBox_GotFocus(object sender, RoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout((sender as RichEditBox));
}
Update
I tried implementing your requirement without custom flyout.
Observations
1 RightTapped event doesnt fire for Textbox. Not sure why. There
is ScrollViewer in ControlTemplate of TextBox(May be that is
the reason why RightTapped event not firing in Textbox)So I added
RightTapped event for Scrollviewer.
2.
private async void ContentElement_RightTapped(object sender, RightTappedRoutedEventArgs e)
{
FlyoutBase.ShowAttachedFlyout(textbox);
await Task.Delay(1000);
FlyoutPresenter canvas = testbutton.FindParent<FlyoutPresenter>();
var popup = canvas.Parent as Popup;
double x = e.GetPosition(e.OriginalSource as UIElement).X;
Debug.WriteLine(x);
popup.IsOpen = false;
popup.SetValue(Canvas.LeftProperty, e.GetPosition(e.OriginalSource as UIElement).X);
popup.IsOpen = true;
}
<Style x:Key="RichEditBoxStyle1" TargetType="RichEditBox">
...
<ScrollViewer x:Name="ContentElement" IsRightTapEnabled="True" RightTapped="ContentElement_RightTapped" AutomationProperties.AccessibilityView="Raw" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled"/>
...
</Style>
<RichEditBox x:Name="textbox" Width="400" HorizontalAlignment="Left" Grid.Row="3" RightTapped="RichEditBox_RightTapped" IsRightTapEnabled="True" GotFocus="RichEditBox_GotFocus" Style="{StaticResource RichEditBoxStyle1}">
<FlyoutBase.AttachedFlyout>
<Flyout >
<Button Content="test" x:Name="testbutton" Click="Button_Click"/>
</Flyout>
</FlyoutBase.AttachedFlyout>
</RichEditBox>
In above code ContentElement_RightTapped is RightTapped Event of ScrollViewer. To add this You have to edit Style of TextBox.
Basically flyout conatins popup that i'm getting using VisualTreeHelper. And setting position(which i get from the event) of PopUp. But somehow PopUp is not getting set to the exact position.
So second option is to go for custom flyout. Refer this Link for how to implement one . You can take code from there
Here is the modified code code
public class TemplatedFlyout:DependencyObject
{
public TemplatedFlyout()
{
}
Popup popUp;
FrameworkElement senderElement;
FrameworkElement frameworkContent;
bool keyboardOpen = false;
InputPane keyboard;
public void Initialization(UIElement sender)
{
senderElement = sender as FrameworkElement;
senderElement.DataContextChanged += (s, e) =>frameworkContent.DataContext = senderElement.DataContext;
popUp = new Popup()
{
ChildTransitions = new Windows.UI.Xaml.Media.Animation.TransitionCollection(),
IsLightDismissEnabled = true
};
popUp.ChildTransitions.Add(new PaneThemeTransition() { Edge = EdgeTransitionLocation.Bottom });
frameworkContent = Template as FrameworkElement;
frameworkContent.DataContext = senderElement.DataContext;
popUp.Child = frameworkContent;
FocusKeeper();
if(sender is RichEditBox || sender is TextBox)
{
(sender as FrameworkElement).Loaded += TemplatedFlyout_Loaded;
}
//else
// sender.Tapped += (s, e) => Show(e);
}
private void TemplatedFlyout_Loaded(object sender, RoutedEventArgs e)
{
(sender as FrameworkElement).FindElementInVisualTree<ScrollViewer>().RightTapped += (s, e1) => Show(e1);
}
public static readonly DependencyProperty TemplateProperty = DependencyProperty.Register(nameof(Template), typeof(object), typeof(TemplatedFlyout), new PropertyMetadata(null));
public object Template
{
get { return (object) GetValue(TemplateProperty); }
set { SetValue(TemplateProperty, value); }
}
void FocusKeeper()
{
keyboard = InputPane.GetForCurrentView();
popUp.Closed += (s, e) =>
{
if(keyboardOpen)
{
popUp.IsOpen = true;
}
};
if(keyboard!=null)
{
keyboard.Showing += (s, e) => keyboardOpen = true;
keyboard.Hiding += (s, e) => keyboardOpen = false;
}
}
public async void Show(RightTappedRoutedEventArgs args)
{
try
{
popUp.RequestedTheme = ((Window.Current.Content as Frame).Content as Page).RequestedTheme;
popUp.IsOpen = true;
frameworkContent.UpdateLayout();
var top = Math.Abs(senderElement.ActualHeight+frameworkContent.ActualHeight+10-Window.Current.Bounds.Height);
var left = args.GetPosition(args.OriginalSource as UIElement).X;
if (frameworkContent is Panel)
{
var panel = frameworkContent as Panel;
if (panel.Children.Any())
{
if (panel.Children.First() is Control)
{
(panel.Children.First() as Control).Focus(FocusState.Keyboard);
}
}
}
popUp.SetValue(Canvas.TopProperty, top);
popUp.SetValue(Canvas.LeftProperty, left);
}
catch(Exception e)
{
}
}
}
public class Extensions:DependencyObject
{
public static void SetFlyout(UIElement element, TemplatedFlyout value)
{
element.SetValue(FlyoutProperty, value);
}
public static TemplatedFlyout GetFlyout(UIElement element)
{
return (TemplatedFlyout)element.GetValue(FlyoutProperty);
}
public static readonly DependencyProperty FlyoutProperty = DependencyProperty.Register(nameof(FlyoutProperty), typeof(TemplatedFlyout), typeof(Extensions), new PropertyMetadata(null, TemplateFlyoutChanged));
private static void TemplateFlyoutChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var uiSender = d as UIElement;
var flyout = e.NewValue as TemplatedFlyout;
flyout.Initialization(uiSender);
}
}
public static class VisualExtensions
{
public static T FindElementInVisualTree<T>(this DependencyObject parentElement) where T : DependencyObject
{
var count = VisualTreeHelper.GetChildrenCount(parentElement);
if (count == 0) return null;
for (int i = 0; i < count; i++)
{
var child = VisualTreeHelper.GetChild(parentElement, i);
if (child != null && child is T)
return (T)child;
else
{
var result = FindElementInVisualTree<T>(child);
if (result != null)
return result;
}
}
return null;
}
}
<RichEditBox IsRightTapEnabled="True" >
<local:Extensions.Flyout>
<local:TemplatedFlyout >
<local:TemplatedFlyout.Template>
<StackPanel>
<TextBlock Text="test1"/>
<TextBlock Text="test1"/>
</StackPanel>
</local:TemplatedFlyout.Template>
</local:TemplatedFlyout>
</local:Extensions.Flyout>
</RichEditBox>
Update 2
You cant add to existing Contextmenu of TextBox. To modify the context menu here is the sample

Detect which child control received a Pointer* event

I have a container control that is handling PointerPressed and PointerMoved events.
The container contains a set of buttons.
At the point of handling the event, how can I determine which button actually received it?
mainPage.AddHandler(PointerPressedEvent, new PointerEventHandler(pointerPressedHandler), true);
private void pointerPressedHandler(object sender, PointerRoutedEventArgs e)
{
var p = e.GetCurrentPoint(null); // maybe can be done using position info?
var s = e.OriginalSource as Border; // OriginalSource is a Border, not the Button, and I don't seem to be able to get to the Button from the Border
// todo - determine which button was clicked
}
This works:
private void pointerPressedHandler(object sender, PointerRoutedEventArgs e)
{
var p = e.GetCurrentPoint(null);
var elements = VisualTreeHelper.FindElementsInHostCoordinates(p.Position, mainPage, false);
Button foundButton;
foreach (var item in elements)
{
foundButton = item as Button;
if (foundButton != null)
{
System.Diagnostics.Debug.WriteLine("found button: " + foundButton.Name);
}
}
}

Add new Item and Edit Item in silverlight DataForm not correctly updating SharePoint List

I am trying to make a simple Silverlight application that will be hosted on a SharePoint site.
I am reading the information from the list "testlist" and I am trying to use a dataform control to edit, add and delete data from the list. I am able to delete just fine. When I try to add it adds a new entry with the data from the item previously viewed and I am unable to edit current Items whatsoever. Here is my code:
namespace SP2010
{
public partial class MainPage : UserControl
{
ClientContext context;
List customerList;
ListItemCollection allCustomers;
public MainPage()
{
this.Loaded += new RoutedEventHandler(MainPage_Loaded);
InitializeComponent();
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
this.DataContext = this;
context = new ClientContext(ApplicationContext.Current.Url);
customerList = context.Web.Lists.GetByTitle("testlist");
context.Load(customerList);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml =#"<View><Query></Query><RowLimit>1000</RowLimit></View>";
allCustomers = customerList.GetItems(camlQuery);
context.Load(allCustomers);
context.ExecuteQueryAsync(new ClientRequestSucceededEventHandler(OnRequestSucceeded), new ClientRequestFailedEventHandler(OnRequestFailed));
}
private void OnRequestSucceeded(Object sender, ClientRequestSucceededEventArgs args)
{
Dispatcher.BeginInvoke(DisplayListData);
}
private void OnRequestFailed(Object sender, ClientRequestFailedEventArgs args)
{
MessageBox.Show(args.ErrorDetails + " " + args.Message);
}
public ObservableCollection<SPCustomers> Printers
{
get
{
if (printers == null)
{
printers = new ObservableCollection<SPCustomers>();
foreach (ListItem item in allCustomers)
{
printers.Add(new SPCustomers
{
IPAddress = item["Title"].ToString(),
Make = item["make"].ToString(),
Model = item["model"].ToString(),
xCord = item["x"].ToString(),
yCord = item["y"].ToString(),
id = Convert.ToInt32(item["ID"].ToString())
});
}
}
return (printers);
}
}
private ObservableCollection<SPCustomers> printers;
private void DisplayListData()
{
dataForm1.DataContext = Printers;
}
private void dataForm1_EditEnded(object sender, DataFormEditEndedEventArgs e)
{
if (e.EditAction == DataFormEditAction.Commit)
{
if (dataForm1.IsItemChanged)
{
customerList = context.Web.Lists.GetByTitle("testlist");
SPCustomers printer = dataForm1.CurrentItem as SPCustomers;
ListItem items = customerList.GetItemById(printer.id);
items["Title"] = printer.IPAddress;
items["make"] = printer.Make;
items["model"] = printer.Model;
items["x"] = printer.xCord;
items["y"] = printer.yCord;
items.Update();
context.ExecuteQueryAsync(OnRequestSucceeded, OnRequestFailed);
}
}
}
private void dataForm1_AddingNewItem(object sender, DataFormAddingNewItemEventArgs e)
{
customerList = context.Web.Lists.GetByTitle("testlist");
SPCustomers printe = dataForm1.CurrentItem as SPCustomers;
ListItemCreationInformation itemcreationinfo = new ListItemCreationInformation();
ListItem items = customerList.AddItem(itemcreationinfo);
items["Title"] = printe.IPAddress;
items["make"] = printe.Make;
items["model"] = printe.Model;
items["x"] = printe.xCord;
items["y"] = printe.yCord;
items.Update();
context.ExecuteQueryAsync(OnRequestSucceeded, OnRequestFailed);
}
private void dataForm1_DeletingItem(object sender, System.ComponentModel.CancelEventArgs e)
{
SPCustomers printer = dataForm1.CurrentItem as SPCustomers;
ListItem oListItem = customerList.GetItemById(printer.id);
oListItem.DeleteObject();
context.ExecuteQueryAsync(OnRequestSucceeded, OnRequestFailed);
}
}
}
and my dataform:
<df:DataForm ItemsSource="{Binding}" Height="276" HorizontalAlignment="Left" Margin="12,12,0,0" Name="dataForm1" VerticalAlignment="Top" Width="376" EditEnded="dataForm1_EditEnded" AddingNewItem="dataForm1_AddingNewItem" DeletingItem="dataForm1_DeletingItem" CommandButtonsVisibility="All" />
Thanks for the help.
update: changed to this will answer in like 7 hours when it lets me
never mind I figured it out I changed my editended to this and deleted my addingNewitem method entirely. Now I just have to hide the ID field and it will be working perfectly
private void dataForm1_EditEnded(object sender, DataFormEditEndedEventArgs e)
{
if (e.EditAction == DataFormEditAction.Commit)
{
customerList = context.Web.Lists.GetByTitle("testlist");
SPCustomers printer = dataForm1.CurrentItem as SPCustomers;
ListItem items;
if (printer.id != 0)
{
items = customerList.GetItemById(printer.id);
}
else
{
ListItemCreationInformation itemcreationinfo = new ListItemCreationInformation();
items = customerList.AddItem(itemcreationinfo);
}
items["Title"] = printer.IPAddress;
items["make"] = printer.Make;
items["model"] = printer.Model;
items["x"] = printer.xCord;
items["y"] = printer.yCord;
items.Update();
context.ExecuteQueryAsync(OnRequestSucceeded, OnRequestFailed);
}
}