I have two Labels, and I want to remove the vertical space between them.
There is my result
I tried to set Margin="0", but the space appear anyway.
<Label Text="Label 01" TextColor="White" FontSize="25" Margin="0" />
<Label Text="Label 02" TextColor="White" FontSize="25" Margin="0" />
Labels have, per default, an extra padding in top. Also, careful with the container you are putting them in, remove spacing in case of a StackLayout and RowSpacing in case of grids.
You can override label extra padding with a custom renderer like this one:
using Android.Content;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;
using XF.LabelPadding.Droid.Renderers;
[assembly: ExportRenderer(typeof(Label), typeof(MyLabelRenderer))]
namespace YourNameSpace.Droid.Renderers
{
public class MyLabelRenderer : LabelRenderer
{
public MyLabelRenderer(Context context) : base(context)
{
}
protected override void OnElementChanged(ElementChangedEventArgs<Label> e)
{
base.OnElementChanged(e);
Control?.SetIncludeFontPadding(false);
}
}
}
I'm using Maui, and what I did is set the padding to minus.
<Label Text="SING IN" TextColor="#FFFFFF" FontSize="90" Padding="-5,-20,-5,-5"></Label>
Related
So, I have a custom control, CusConA, that works basically like a textbox - you type amount of money that you need, and I have a button below, whom by getting clicked saves that amount(from CusConA) somewhere, and that is working fine.
But I want to try the same functionality basically by clicking anywhere on that page (something like OnBlur in asp.net), or to be precise, when my CusConA is not in focus anymore.
By doing what is shown with the --> in code, I achieved sort of a solution, this way when pressing anywhere, even if I never even tried to write an amount, the command is being executed.
So, to try to circle my question, I need this command to execute only after typing some amount, and clicking somewhere alse after. How can I do that?
<Frame
Margin="55,0"
Padding="0"
BorderColor="Blue"
CornerRadius="30">
<StackLayout Orientation="Horizontal">
<Label
Margin="10"
FontAttributes="Bold"
FontSize="20"
HorizontalTextAlignment="Center"
Text="RSD"
TextColor="Some text"
VerticalTextAlignment="Center" />
<customControls:CusConA
Margin="0,0,15,0"
HorizontalOptions="FillAndExpand"
Keyboard="Numeric"
Placeholder="0,00"
PlaceholderColor="Gray"
Text="Some text"
TextColor="Black" >
--> <customControls:CusConA.Behaviors>
<xct:EventToCommandBehavior EventName="Unfocused" Command="{Binding DoSomething}" ></xct:EventToCommandBehavior>
</customControls:CusConA.Behaviors>
</customControls:CusConA>
</StackLayout>
</Frame>
Can you change DoSomething to check whether the amount has been typed? Might involve adding a boolean property to your control:
bool CanExecute { get; set; }
Then have "amount" bound to a property whose setter sets CanExecute = true; or CanExecute = false;, depending on whether an amount has been typed. Something like:
string Amount
{
...
set {
_amount = value;
myControl.CanExecute = value.Count > 0;
}
}
Then change DoSomething body to
if (this.CanExecute) { ... }
Alternatively, other techniques can be used to have a change to Amount trigger a change to a property on myControl.
The essential points are:
Adding CanExecute property, so control can be told when it is valid to execute that command.
Using some technique to bind or trigger myControl.CanExecute change, from elsewhere.
I think you can use EventToCommandBehavior to achieve this function.
There is an example of an EventToCommandBehavior in the Xamarin.Forms samples (see here).
<ContentPage.BindingContext>
<focusapp:MyViewModel></focusapp:MyViewModel>
</ContentPage.BindingContext>
<StackLayout>
<Entry>
<Entry.Behaviors>
<Behaviors:EventToCommandBehavior
EventName="Unfocused"
Command="{Binding EntryUnfocused}" />
</Entry.Behaviors>
</Entry>
</StackLayout>
And define EntryUnfocused in your viewmodel.cs (e.g. MyViewModel) just as follows:
MyViewModel.cs
public class MyViewModel
{
public ICommand EntryUnfocused { get; protected set; }
public MyViewModel() {
EntryUnfocused = new Command(CompletedCommandExecutedAsync);
}
private void CompletedCommandExecutedAsync(object param)
{
System.Diagnostics.Debug.WriteLine("------------> come here....");
}
}
Currently I am playing around with .Net Maui but I maybe it's the same behavior as Xamarin.
I've created a simple Search-Control which is based on a ContentView.
ObjectSearchControl.xaml
<ContentView
x:Class="DeepBlue.Controls.ObjectSearchControl"
xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:DeepBlue.Converter"
xmlns:selector="clr-namespace:DeepBlue.Helpers"
x:Name="MySearchControl">
<StackLayout
Orientation="Vertical"
VerticalOptions="FillAndExpand">
<SearchBar
x:Name="ObjectSearchBar"
IsSpellCheckEnabled="False"
Keyboard="Text"
Placeholder="{Binding SearchBarPlaceholderText}"
TextChanged="ObjectSearchBar_TextChanged" />
<CollectionView
x:Name="ObjectResultView"
HeightRequest="500"
ItemsSource="{Binding DataSource}"
SelectionChanged="ObjectResultView_SelectionChanged">
</CollectionView>
</StackLayout>
</ContentView>
ObjectSearchControl.xaml.cs
public partial class ObjectSearchControl : ContentView
{
public static readonly BindableProperty SearchBarPlaceholderTextProperty
= BindableProperty.Create(nameof(SearchBarPlaceholderText), typeof(string),
typeof(ObjectSearchControl), string.Empty);
public static readonly BindableProperty DataSourceProperty
= BindableProperty.Create(nameof(DataSource), typeof(object),
typeof(ObjectSearchControl));
public ObjectSearchControl()
{
InitializeComponent();
Content.BindingContext = this;
}
public string SearchBarPlaceholderText
{
get => (string)GetValue(SearchBarPlaceholderTextProperty);
set => SetValue(SearchBarPlaceholderTextProperty, value);
}
public object DataSource
{
get => (object)GetValue(DataSourceProperty);
set => SetValue(DataSourceProperty, value);
}
}
This ContentView I've inserted in my Page
<StackLayout
x:Name="SelectFishingSection"
HeightRequest="600"
HorizontalOptions="FillAndExpand"
Orientation="Vertical"
VerticalOptions="FillAndExpand">
<controls:ObjectSearchControl
DataSource="{Binding NonFilterdDataSource}"
HeightRequest="550"
HorizontalOptions="FillAndExpand"
SearchBarPlaceholderText="Placeholder"
VerticalOptions="FillAndExpand" />
</StackLayout>
After running the code the control rendered and the Placeholdertext in the SearchBar is set correct. So I thought the implementation of the binding is correct. But in my CollectionView no element is rendered.
So I debugged a lot and found out that the BindingContext is set 2 times. When I initialize the control all the properties have got NULL values. -> seems okay
Then the control is appearing and I get the elements from DB and set them to "DataSource".
<ContentPage.Behaviors>
<mctBehaviors:EventToCommandBehavior Command="{Binding SetDataSourcesCommand}" EventName="Appearing" />
</ContentPage.Behaviors>
private async Task SetDataSources()
{
try
{
IsBusy = true;
NonFilterdDataSource = new ObservableCollection<MyTestModel>(await DataService.GetAll());
}
finally
{
IsBusy = false;
}
}
That's also called and seems correct. After that BindingContext is set (OnBindingContextChanged is called in my ObjectSearchControl.xaml.cs) and all properties (SearchBarPlaceholderText and DataSource) have got correct values. At this point in DataSource there are 9 Elements!
If I continue debugging the DataSource is set to NULL and also the BindingContext is set to NULL! But I don't understand why?
Output window in VS shows only "External Code" and I can not figure out why this is happening.
I found a few similar questions but none of the could solve my problem.
After analysing the "External Code" in VS I found out that the source of the problem must be somewhere in the measurement for the control. So I removed VerticalOptions="FillAndExpand" from my controls:ObjectSearchControl implemention and after that the problem was gone. BindingContext is set only one time and everything is working as expected!
bit stuck on this.
Have a list view and I want to change the theme to match the rest of my app.
Been following a few examples of how to change the selected item back color which I have working really well using custom renders, mainly this example
https://blog.wislon.io/posts/2017/04/11/xamforms-listview-selected-colour
However no example I've been able to find addresses the fore color of the selected items.
Is that something I would do with custom renders as with the background or am I backing up the wrong tree?
My list view definition is as follows
<ListView.ItemTemplate>
<DataTemplate>
<customControls:ExtendedViewCell SelectedBackgroundColor="#5DB8B3">
<ViewCell.View>
<StackLayout VerticalOptions="StartAndExpand">
<Label Text="{Binding AttributeName}"
FontSize="Small"
FontAttributes="Bold"/>
<Label Text="{Binding Description}"
FontSize="Small"/>
<Label Text="{Binding CreditorName}"
FontSize="Small"/>
</StackLayout>
</ViewCell.View>
</customControls:ExtendedViewCell>
</DataTemplate>
</ListView.ItemTemplate>
Appreciate any feedback thank
You can do this (Without a custom renderer) by adding another property to the object is bound to, and binding TextColor on the label to this new property.
Assuming your bound object looks something like this
public class BoundObject
{
public string AttributeName { get; set; }
public string Description { get; set; }
public string CreditorName { get; set; }
public int id { get; set; }
public Color TextColor { get; set; }
}
XAML
Note the ListView control added, with a name property and an ItemSelected event.
<ListView x:Name="myList" ItemSelected="myListSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout VerticalOptions="StartAndExpand">
<Label Text="{Binding AttributeName}"
FontSize="Small"
FontAttributes="Bold"
TextColor="{Binding TextColor}"
/>
<Label Text="{Binding Description}"
FontSize="Small"
TextColor="{Binding TextColor}"
/>
<Label Text="{Binding CreditorName}"
FontSize="Small"
TextColor="{Binding TextColor}"
/>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code Behind
Most of the magic happens in the code behind. Note that I'm just adding a few items to the list on start here - just for debug purposes. It's important to note that the start color is also given at the time the list needs to be created.
I've also added an ID field to the BoundObject, so we can more easily identify which object we have selected.
List<BoundObject> listItems = new List<BoundObject>();
public YourPage()
{
InitializeComponent();
for (int i = 0; i < 10; i++)
{
listItems.Add(new BoundObject() { id=i, AttributeName = "Attribute " + i, Description = i + " description", CreditorName = "Creditor: " + i, TextColor = Color.Blue });
}
myList.ItemsSource = listItems;
}
private void myListSelected(object sender, SelectedItemChangedEventArgs e)
{
if (((ListView)sender).SelectedItem == null)
return;
//Get the item we have tapped on in the list. Because our ItemsSource is bound to a list of BoundObject, this is possible.
var selection = (BoundObject)e.SelectedItem;
//Loop through our List<BoundObject> - if the item is our selected item (checking on ID) - change the color. Else - set it back to blue
foreach(var item in listItems)
{
if (item.id == selection.id)
item.TextColor = Color.Red;
else
item.TextColor = Color.Blue;
}
//ItemsSource must be set to null before it is re-assigned, otherwise it will not re-generate with the updated values.
myList.ItemsSource = null;
myList.ItemsSource = listItems;
}
The key points to the code-behind are...
New property TextColor on your bound object, of type Color
Store your BoundObject in a List<BoundObject>
When populating your list for the first time, set the TextColor property in your BoundObject
In the ItemSelected event for your list, get the current selection, and update the List<BoundObject> setting the colours as your conditions need
Set the list ItemSource to null, and re-assign it to the (now updated) List<BoundObject>
Can achieve through,
a custom renderer , however with this approach the color is not applied when the cell includes a ContextAction.
Using Custom Renderer,
From bugzilla
Using Cross Platform Way (binding), this approach applying the color to all cells(layout) that including a ContextAction
Obviously in Xamarin Forms,
Possible ways to achevie
Stack Overflow discussion
I'm working on a view (called 'Familify') which shows users a list of assets, and allows them to delete an asset from the list. The assets are stored in an ObservableCollection in the ViewModel, so the command to delete simply takes the asset object and removes it from collection. I'm having issues getting the 'delete' functionality working. Here is the XAML and codebehind:
Familify.xaml
<ListView
ItemsSource="{Binding Assets}">
<ListView.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="80px" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="150px" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="60px" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
Text="{Binding number}" FontFamily="Consolas"/>
<TextBlock
Grid.Column="1"
Text="{Binding type}"/>
<TextBlock
Grid.Column="2"
Text="add binding here"/>
<TextBlock
Grid.Column="3"
Text="add binding here"/>
<Button
Command="{x:Bind ViewModel.RemoveAssetCommand}"
CommandParameter="{Binding}"
Content=""
FontFamily="Segoe MDL2 Assets"
Grid.Column="4">
</Button>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Familify.xaml.cs
namespace asset_manager.Views
{
public sealed partial class Familify : UserControl
{
FamilifyViewModel ViewModel { get; set; }
public Familify()
{
this.InitializeComponent();
DataContextChanged += (s, e) =>
{
ViewModel = DataContext as FamilifyViewModel;
};
}
}
}
The idea is that clicking the button removes the asset from the list. (Just to note, the normal binding showing number, type, etc. is working correctly.) My thinking so far:
Try to use binding to access the RemoveAssetCommand stored in the View Model for the page. However, I couldn't get ancestral binding to work (i.e. trying to find the data context of an element higher up in the XAML hierarchy didn't work because findAncestor isn't a thing in UWP.)
x:Bind looked like a good solution, because it uses an explicit path to the property. So, if I declared ViewModel in my code behind, I could use x:Bind ViewModel.property. All well and good. I did just that, and intellisense allowed me to access the ViewModel.RemoveAssetCommand when typing it out.
However, this did not work, because I get the error no DataType defined for DataTemplate. This makes sense, so I tried two things.
x:DataType="Models:Asset" (put in the DataTemplate tag above) is the model being shown in the data template, so I tried that first. Of course, the command is not declared in the model, it's declared in the View Model, so that didn't work.
I instead tried x:DataType="ViewModels:FamilifyViewModel", thinking I could just use x:Bind with that. However, I then got an error that it couldn't cast an object of type Asset to FamilifyViewModel. This makes sense, because the object getting passed to this data template is of the type Asset.
This is a pain, because the whole reason I thought x:Bind would work is that I could just access the property directly from the ViewModel in the codebehind.
Explicitly stated, 1) is it possible to use x:Bind within a data template to access a base level property (in this case, a Prism command) on the ViewModel? and 2) is there a better way to go about implementing this functionality?
Is it possible to use x:Bind within a data template to access a base level property (in this case, a Prism command) on the ViewModel?
Yes, if you want to access a base level, you can reassign DataContext of button like following:
<Button DataContext="{Binding ElementName=Familily, Path=DataContext}"/>
The Family is the name of UserControl.
is there a better way to go about implementing this functionality?
When you put commad in the ViewModel and bind the button as above. The the bind item of button will become Family DataContext. So you could not invoke delete action directly in the ViewModel.
The best practice to implement this functionality is that put the RemoveAssetCommand in the Asset class. And use the ItemsSource of ListView as Button CommandParameter.
<Button
Command="{Binding RemoveAssetCommand}"
CommandParameter="{Binding ElementName=MyListView, Path=ItemsSource}"
Content=""
FontFamily="Segoe MDL2 Assets"
Grid.Column="4">
</Button>
Asset.cs
public class Asset
{
public string number { get; set; }
public string type { get; set; }
public ICommand RemoveAssetCommand
{
get
{
return new CommandHandler<ObservableCollection<Asset>>((item) => this.RemoveAction(item));
}
}
private void RemoveAction(ObservableCollection<Asset> items)
{
items.Remove(this);
}
}
ViewModel.cs
public class FamilifyViewModel
{
public ObservableCollection<Asset> Assets = new ObservableCollection<Asset>();
public FamilifyViewModel()
{
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
Assets.Add(new Asset { number = "100001", type = "hello" });
}
}
Yes, i have googled for it, this solution doesn't do the trick:
Disable navigation on FlipView
Because i want to remain changing items with animations, but only programmatically.
I have investigated the FlipView template and found that all interactions/animations etc. are built using the ScrollingHost by name:
<ScrollViewer x:Name="ScrollingHost" AutomationProperties.AccessibilityView="Raw" BringIntoViewOnFocusChange="{TemplateBinding ScrollViewer.BringIntoViewOnFocusChange}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" HorizontalSnapPointsType="MandatorySingle" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" IsTabStop="False" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsHorizontalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsHorizontalScrollChainingEnabled}" IsVerticalScrollChainingEnabled="{TemplateBinding ScrollViewer.IsVerticalScrollChainingEnabled}" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Padding="{TemplateBinding Padding}" TabNavigation="{TemplateBinding TabNavigation}" VerticalSnapPointsType="MandatorySingle" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" ZoomMode="Disabled">
<ItemsPresenter/>
</ScrollViewer>
So, i have created a custom class MyFlipView and derivered from FlipView, and overrided MouseWheel ( this gives me the needed behavior on desktop ), and deleted navigation buttons from template ( this also limits user interactions ). But the only thing that remains, user is still able to drag the items by pointer ( tablets, phones, maybe even PC with touch screens ). here is my code:
public class MyFlipView : FlipView
{
ScrollViewer scroll;
public MyFlipView()
{
}
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
scroll = GetTemplateChild("ScrollingHost") as ScrollViewer;
scroll.HorizontalScrollMode = ScrollMode.Disabled;
scroll.VerticalScrollMode = ScrollMode.Disabled;
scroll.VerticalScrollBarVisibility = ScrollBarVisibility.Disabled;
scroll.HorizontalScrollBarVisibility = ScrollBarVisibility.Disabled;
scroll.IsHorizontalRailEnabled = false;
scroll.IsVerticalRailEnabled = false;
scroll.IsVerticalScrollChainingEnabled = false;
scroll.IsHorizontalScrollChainingEnabled = false;
scroll.IsHoldingEnabled = false;
}
protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
{
e.Handled = true;
//base.OnPointerWheelChanged(e);
}
}
As you can see i tried do disable all the scrolling in the ScrollingHost, but still it is possible to switch items on touchscreens. How can i disable them also?
Set the FlipView's IsHitTestVisible property to false.
Then set KeyboardNavigation.DirectionalNavigation to none
Which is basically saying "You can't touch me or tab to me"
Thomas Schneiter's answer would still allow it to be reached via tabbing / other buggy methods of navigation.
If you don't need any interaction with the FlipView, an easy but... well kinda ugly solution is to put a (almost) transparent rectangle on top of your FlipView.
<Grid>
<FlipView ... />
<Rectangle Fill="White" Opacity="0.01" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
</Grid>
Over a year later and still no good solution for disabling FlipView's. Here's what I ended up doing which seems to do the trick without having to create a new FlipView control.
Edit the ControlTemplate and remove all the navigation buttons. Add a transparent background to you DataTemplate container. Add a PointerWheelChanged event handler to the DataTemplate container and have it set e.Handled = true;. Finally, add a SelectionChanged event handler to the FlipView and have it reset the selected item back to the original.
XAML
<FlipView x:Name="MyFlipView" ItemsSource="{x:Bind Items,Mode=OneWay}" SelectionChanged="FlipView_SelectionChanged">
<FlipView.ItemTemplate>
<DataTemplate>
<Grid Background="Transparent" PointerWheelChanged="Item_PointerWheelChanged">
<!--You Item XAML-->
</Grid>
</DataTemplate>
</FlipView.ItemTemplate>
<FlipView.Template>
<ControlTemplate TargetType="FlipView">
<Grid>
<!--Default ScrollViewer settings omitted, but no changes needed-->
<ScrollViewer>
<ItemsPresenter />
</ScrollViewer>
</Grid>
</ControlTemplate>
</FlipView.Template>
</FlipView>
Code Behind
private bool _isDisabled;
private object _selectedItem;
public ObservableCollection<object> Items { get; } = new ObservableCollection<object>();
//methods for setting Items, _isDisabled, and _selectedItem omitted
private void Item_PointerWheelChanged(object sender, PointerRoutedEventArgs e)
{
//this prevents the wheel from changing the items
e.Handled = _isDisabled;
}
private void FlipView_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
//Can't find a way to disable keyboard from changing items so we'll monitor the change and flip it back
if (_isDisabled)
{
this.SetupSelectedItem();
}
}
private void SetupSelectedItem()
{
//do a check here to prevent SelectionChanged events from firing.
if (this.MyFlipView.SelectedItem != _selectedItem)
{
this.MyFlipView.SelectedItem = _selectedItem;
}
}
UPDATE
Ok, TouchScreen was still having some problems so I took another stab at it. There are two levels we need to work on, the FlipViewItem and the FlipView. Unfortunately we have to sub-class these because there aren't any overrides we can do to interrupt the default behavior. I also wanted to use binding to be able to turn the flipping on or off. This only supports Horizontal orientation but can easily be adjusted to support Vertical.
Custom FlipViewItem is needed to control the mouse and keyboard.
public sealed class GalleryFlipViewItem : FlipViewItem
{
public bool IsFlipEnabled { get; set; }
protected override void OnKeyDown(KeyRoutedEventArgs e)
{
e.Handled = !this.IsFlipEnabled;
base.OnKeyDown(e);
}
protected override void OnPointerWheelChanged(PointerRoutedEventArgs e)
{
e.Handled = !this.IsFlipEnabled;
base.OnPointerWheelChanged(e);
}
}
Custom FlipView is needed to control the touch and trickle the setting to the custom FlipViewItem.
public sealed class GalleryFlipView : FlipView
{
public static readonly DependencyProperty IsFlipEnabledProperty =
DependencyProperty.Register("IsFlipEnabled", typeof(bool), typeof(GalleryFlipView), new PropertyMetadata(true, IsFlipEnabledChanged));
private static void IsFlipEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
if (d is GalleryFlipView control)
{
if (control.GetTemplateChild("ScrollingHost") is ScrollViewer scrollViewer)
{
scrollViewer.HorizontalScrollMode = control.IsFlipEnabled ? ScrollMode.Auto : ScrollMode.Disabled;
}
if (control.ContainerFromItem(control.SelectedItem) is GalleryFlipViewItem flipViewItem)
{
flipViewItem.IsFlipEnabled = control.IsFlipEnabled;
}
}
}
public bool IsFlipEnabled
{
get { return (bool)GetValue(IsFlipEnabledProperty); }
set { SetValue(IsFlipEnabledProperty, value); }
}
protected override DependencyObject GetContainerForItemOverride()
{
return new GalleryFlipViewItem
{
IsFlipEnabled = this.IsFlipEnabled
};
}
}
Now we need to add the styles for each of these controls. I just copied the default styles for FlipViewItem and FlipView. I made a small adjustment to the FlipView by removing the up/down buttons and added binding to control the left/right button's visibility. To do this, wrap the original button in a grid and then use a converter to convert the bool to a visibility enum.
<Grid HorizontalAlignment="Left" VerticalAlignment="Center" Visibility="{Binding IsFlipEnabled,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BooleanToVisibleConverter}}">
<Button x:Name="PreviousButtonHorizontal" Height="36" IsTabStop="False" Template="{StaticResource HorizontalPreviousTemplate}" UseSystemFocusVisuals="False" Width="20" />
</Grid>
<Grid HorizontalAlignment="Right" VerticalAlignment="Center" Visibility="{Binding IsFlipEnabled,RelativeSource={RelativeSource TemplatedParent},Converter={StaticResource BooleanToVisibleConverter}}">
<Button x:Name="NextButtonHorizontal" Height="36" IsTabStop="False" Template="{StaticResource HorizontalNextTemplate}" UseSystemFocusVisuals="False" Width="20" />
</Grid>
Since IsFlipEnabled is a DependencyProperty you can use binding, xaml, or code behind to control it.
<controls:GalleryFlipView IsFlipEnabled="False">
Finally, this seems like the right solution. So frustrating we have to do so much work to simply turn this feature on and off.