I've specified a control template in my App.xaml:
<?xml version="1.0" encoding="utf-8"?>
<Application xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="MyApp.App">
<Application.Resources>
<ResourceDictionary>
<ControlTemplate x:Key="PageTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<BoxView Grid.Row="0"
Grid.RowSpan="3"
BackgroundColor="#2B653E"/>
<Label Grid.Row="1"
TextColor="White"
HorizontalOptions="Center"
FontSize="36"
FontFamily="TimesNewRomanPS-BoldMT"
Text="{TemplateBinding BindingContext.HeadingText}"/>
<Image Grid.Row="2"
Grid.RowSpan="2"
Source="TGL_BG"/>
<ContentPresenter Grid.Row="4"/>
</Grid>
</ControlTemplate>
</ResourceDictionary>
</Application.Resources>
</Application>
You can see I've got one of my controls databound:
Text="{TemplateBinding BindingContext.HeadingText}"
The control template works fine, I can add it to a page without any problems, except for the bound property doesn't display:
Here is my page code:
<?xml version="1.0" encoding="UTF-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MyApp.Pages.ContactPage">
<ContentView ControlTemplate="{StaticResource PageTemplate}">
<StackLayout>
<!-- Page content here, removed for brevity -->
</StackLayout>
</ContentView>
</ContentPage>
Here is my code behind:
using System;
using System.Collections.Generic;
using MyApp.ViewModels;
using Xamarin.Forms;
namespace MyApp.Pages
{
public partial class ContactPage : ContentPage
{
public ContactPage(ContactPageViewModel viewModel)
{
InitializeComponent();
viewModel.Navigation = Navigation;
BindingContext = viewModel;
}
}
}
Here you can see I'm setting the binding context to the ViewModel (which works for everything outside the template). And here is my ViewModel:
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;
using MyApp.Helpers;
using Xamarin.Forms;
namespace MyApp.ViewModels
{
public class ContactPageViewModel : ViewModel
{
public string HeadingText = "Contact Us";
//Other properties and commands here, removed for brevity
}
}
As you can see I've got a public property here called 'HeadingText' which is what I'm binding to in the view.
I've read the documentation and a few examples/tutorials. According to what I can see this should work. Can anyone see what's wrong with this?
EDIT:
I've now got this working. In my ViewModel, I changed this:
public string HeadingText = "Contact Us";
to this:
public string HeadingText
{
get
{
return "Contact Us";
}
}
Leaving the question open now as hoping someone can provide an explanation.
binding only works with public properties
// this is a field, not a property
public string HeadingText = "Contact Us";
// this is a property
public string HeadingText
{
get
{
return "Contact Us";
}
}
Related
I'm starting understanding .Net MAUI with an online video.
I'm trying to customize a page with 3 buttons, 1 for a counter, 1 for a second page and 1 for a flyoutpage.
Counter and second page are ok, flyout page doesn't display but force the App to exit.
My code for the button that calls the flyout page is this, located in the MainPage.xml.cs :
private void FlyClicked(object sender, EventArgs e)
{
Navigation.PushAsync(new Flyout1());
}
Can anybody explain me the reason of this ?
Many Thanks
According to your description, the Flyout1 should be a FlyoutPage. You can refer to the code below on how to create a FlyoutPage. I test it and it can display it.
Flyout1:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<FlyoutPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppDualScreen.Flyout1"
xmlns:local="clr-namespace:MauiAppDualScreen"
>
<FlyoutPage.Flyout>
<local:FlyoutMenuPage x:Name="flyoutPage" />
</FlyoutPage.Flyout>
<FlyoutPage.Detail>
<NavigationPage>
<x:Arguments>
<local:MainPage />
</x:Arguments>
</NavigationPage>
</FlyoutPage.Detail>
</FlyoutPage>
Code-behind:
public partial class Flyout1 : FlyoutPage
{
public Flyout1()
{
InitializeComponent();
}
}
The following example shows the definition of the FlyoutMenuPage object, which is of type ContentPage:
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="MauiAppDualScreen.FlyoutMenuPage"
xmlns:local="clr-namespace:MauiAppDualScreen"
Title="FlyoutMenuPage">
<CollectionView x:Name="collectionView"
x:FieldModifier="public"
SelectionMode="Single">
<CollectionView.ItemsSource>
<x:Array Type="{x:Type local:FlyoutPageItem}">
<local:FlyoutPageItem Title="Contacts"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
<local:FlyoutPageItem Title="TodoList"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
<local:FlyoutPageItem Title="Reminders"
IconSource="dotnet_bot.png"
TargetType="{x:Type local:MainPage}" />
</x:Array>
</CollectionView.ItemsSource>
<CollectionView.ItemTemplate>
<DataTemplate>
<Grid Padding="5,10">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding IconSource}" />
<Label Grid.Column="1"
Margin="20,0"
Text="{Binding Title}"
FontSize="20"
FontAttributes="Bold"
VerticalOptions="Center" />
</Grid>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</ContentPage>
Code-behind:
public partial class FlyoutMenuPage : ContentPage
{
public FlyoutMenuPage()
{
InitializeComponent();
}
}
The flyout page consists of a CollectionView that's populated with data by setting its ItemsSource property to an array of FlyoutPageItem objects. The following example shows the definition of the FlyoutPageItem class:
public class FlyoutPageItem
{
public string Title { get; set; }
public string IconSource { get; set; }
public Type TargetType { get; set; }
}
I have written a nice Grid with some other controls like: Entry and Image and now I would like to reuse it the simplest way.
This is my control for Email property:
<Grid
Style="{StaticResource gridEntryStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="9*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="20" />
<RowDefinition Height="7" />
<RowDefinition Height="20" />
</Grid.RowDefinitions>
<controls:ExtendedEntry
Grid.Row="0"
Grid.Column="0"
Text="{Binding UserEmail, Mode=TwoWay}"
Placeholder="{i18n:Translate UserEmailPlaceholder}"
Style="{StaticResource entryStyle}">
<controls:ExtendedEntry.Behaviors>
<behavior:EventToCommandBehavior
EventName="Focused"
Command="{Binding ControlFocusCommand}"
CommandParameter="UserEmail"/>
<behavior:EventToCommandBehavior
EventName="Unfocused"
Command="{Binding ControlUnfocusedCommand}"
CommandParameter="UserEmail"/>
</controls:ExtendedEntry.Behaviors>
</controls:ExtendedEntry>
<Image
Grid.Row="0"
Grid.Column="1"
Source="clear.png"
IsVisible="{Binding IsEntryFocused}"
Style="{StaticResource imageClearStyle}">
<Image.GestureRecognizers>
<TapGestureRecognizer
Command="{Binding ClearCommand}"
CommandParameter="UserEmail"/>
</Image.GestureRecognizers>
</Image>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="lineWhite.png"
Style="{StaticResource imageLineStyle}"/>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="linePure.png"
Style="{StaticResource imageLineStyle}"
IsVisible="{Binding IsError}"/>
<Image
Grid.Row="1"
Grid.Column="0"
Grid.ColumnSpan="2"
Source="lineGradient.png"
Style="{StaticResource imageLineStyle}"
IsVisible="{Binding IsEntryFocused}"/>
<Label
Grid.Row="2"
Grid.Column="0"
Text="{Binding ErrorMessage}"
Style="{StaticResource labelErrorStyle}"
IsVisible="{Binding IsError}"/>
<Image
Grid.Row="2"
Grid.Column="1"
Source="error.png"
Style="{StaticResource imageErrorStyle}"
IsVisible="{Binding IsError}"/>
</Grid>
I would like to reuse it for example as follows:
<usercontrols:EntryControl
MainText="{Binding UserEmail}"
MainTextPlaceholder="{i18n:Translate UserEmailPlaceholder}" />
For now even this simple example is not working and I have no idea how to define Command in this control. For now I have:
public partial class EntryControl : ContentView
{
public EntryControl()
{
InitializeComponent();
}
public static readonly BindableProperty MainTextProperty =
BindableProperty.Create(
propertyName: "MainText",
returnType: typeof(string),
declaringType: typeof(string),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.TwoWay);
public string MainText
{
get { return (string)this.GetValue(MainTextProperty); }
set { this.SetValue(MainTextProperty, value); }
}
public static readonly BindableProperty MainTextPlaceholderProperty =
BindableProperty.Create(
propertyName: "MainTextPlaceholder",
returnType: typeof(string),
declaringType: typeof(string),
defaultValue: string.Empty,
defaultBindingMode: BindingMode.TwoWay);
public string MainTextPlaceholder
{
get { return (string)this.GetValue(MainTextPlaceholderProperty); }
set { this.SetValue(MainTextPlaceholderProperty, value);}
}
}
Is this the right way? or is this even possible in Xamarin.Forms?
XAML:
<?xml version="1.0" encoding="utf-8" ?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
x:Class="ApplicationName.Controls.EntryControl"
Style="{StaticResource gridEntryStyle}">
</Grid>
xaml.cs:
namespace ApplicationName.Controls
{
public partial class EntryControl : Grid
{
public static readonly BindableProperty CommandProperty =
BindableProperty.Create(
propertyName: nameof(Command),
returnType: typeof(ICommand),
declaringType: typeof(EntryControl),
defaultValue: null,
defaultBindingMode: BindingMode.TwoWay);
public string Command
{
get { return (string)this.GetValue(CommandProperty); }
set { this.SetValue(CommandProperty, value); }
}
public EntryControl()
{
InitializeComponent();
}
}
}
using:
xmlns:controls="clr-namespace:ApplicationName.Controls;assembly=ApplicationName"
<controls:EntryLabel/>
Your issue with BindingContext
In short, you have to write down the bindings inside your control like this {Binding UserEmail, Mode=TwoWay, Source={x:Reference myControlTHIS}}, where 'myControlTHIS' is x:Name="TheCategoryHeader".
More info:
BindingContext is everything when it comes to getting things to bind and work right in an MVVM app – WPF or Xamarin. Controls inherit context from the parent control unless a different context is explicitly assigned. That’s what we need to do here. We need to tell each UI element (label, entry, button, etc.) to explicitly look at this control for its context in order to find those BindingProperties we just made. This is one of the rare occasions when we actually give a XAML element a name: When it is going to be referenced by another XAML element within the XAML itself. To the ContentView, add a tag naming the control ‘this’. That’s right. We’re going to keep to the Microsoft naming and have this item refer to itself as 'myControlTHIS'. It makes all of us comfortable and the code and markup easy to read and follow.
We can now use 'myControlTHIS' as a reference source telling the rest of our XAML where to look for properties to bind to.
I am trying to manage dragdrop events on a "TreeView" object in a view with MVVM approach, thus I don't want write hookevent codes in "FormProjectWorksView.xaml.cs"... And following a tutorial on youtube : https://www.youtube.com/watch?v=Cx6YE86XzYE , I tried to get a custom dependency property being populated in xaml designer code in visual studio...But when I type the name of the customDP which is "DragCommand"; it doesn't get recognised, anywhere in the "xaml" file... In my case I tried to use it inside "" Tag..could you help why it doesn't showup in the IDE popup? and doesn't compile of course? Or am I totally in wrong direction to handle such mouseevents on a view separated from viewmodel...And even further actually I am using view switching from MainWindow.xml, which is the starting View of the application...and any other "UserControl-Views" are switched when necessary.
FormProjectWorksView.xaml
<UserControl x:Class="FullProject.Views.FormProjectWorksView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:FullProject.Views"
xmlns:viewmodels="clr-namespace:FullProject.ViewModels"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="5*"/>
</Grid.ColumnDefinitions>
<TreeView x:Name="tv1" Grid.Column="0" ItemsSource="{Binding treeView.Items}"
AllowDrop="True"/>
<Grid x:Name="maingrid" Grid.Column="1" Background="Chartreuse">
<TextBlock Grid.Column="0" Margin="10 " Text="{Binding deneme}" FontSize="28"/>
</Grid>
</Grid>
</UserControl>
FormProjectWorksView.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
namespace FullProject.Views
{
/// <summary>
/// Interaction logic for FormProjectWorksView.xaml
/// </summary>
public partial class FormProjectWorksView : UserControl
{
public ICommand DragCommand
{
get { return (ICommand)GetValue(DragCommandProperty); }
set { SetValue(DragCommandProperty, value); }
}
// Using a DependencyProperty as the backing store for command. This enables animation, styling, binding, etc...
public static readonly DependencyProperty DragCommandProperty =
DependencyProperty.Register("DragCommand", typeof(ICommand), typeof(FormProjectWorksView), new PropertyMetadata(null));
public FormProjectWorksView()
{
InitializeComponent();
}
}
}
MainWindow.xaml
<Window x:Class="FullProject.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:FullProject"
xmlns:viewmodels="clr-namespace:FullProject.ViewModels"
xmlns:views="clr-namespace:FullProject.Views"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Window.Resources>
<DataTemplate DataType="{x:Type viewmodels:MainFormViewModel}">
<views:MainFormView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:GlobalWorksViewModel}">
<views:GlobalWorksView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:GlobalResourcesViewModel}">
<views:GlobalResourcesView/>
</DataTemplate>
<DataTemplate DataType="{x:Type viewmodels:FormProjectWorksViewModel}">
<views:FormProjectWorksView/>
</DataTemplate>
</Window.Resources>
<Grid>
<ContentControl Content="{Binding CurrentViewModel}"/>
</Grid>
</Window>
Here I am using MVVM architecture for developing applications. I have an image inside the listview and the listview binding with a list (ViewAcceptedList). Here I am using TapGestureRecognizer for the image. Inside the image I need to call a command (ChatTappedCommand). I am sharing my code, how I tried to achieve the requirement. I need help from an experienced one.
<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:IC="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
xmlns:Custom="clr-namespace:MTR.Customization" xmlns:pv="clr-namespace:Xamarin.Forms.PancakeView;assembly=Xamarin.Forms.PancakeView" xmlns:local="clr-namespace:MTR.Views"
mc:Ignorable="d"
x:Class="MTR.Views.MailBox.MailBoxPage"
xmlns:behaviors="clr-namespace:MTR.ViewModels.Behavior" xmlns:VM="clr-namespace:MTR.ViewModels"
BackgroundColor="#F8F0F0">
<ContentPage.BindingContext>
<VM:MailBoxPageViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<ListView x:Name="MailboxAcceptedList"
IsVisible="{Binding ViewAcceptedList}"
ItemsSource="{Binding MailedBoxAcceptedList}"
SeparatorColor="Transparent"
VerticalScrollBarVisibility="Never"
HasUnevenRows="True"
RelativeLayout.YConstraint="{ConstraintExpression Type=RelativeToView, ElementName=stackNavigationBar, Property=Height,Constant=2, Factor=2.9}"
RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent, Property=Height, Factor=.8}"
RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent, Property=Width, Factor=1}">
<ListView.Behaviors>
<behaviors:MailBoxListViewBehavior />
</ListView.Behaviors>
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Image x:Name="imgChat"
Source="chat_32px.png"
HeightRequest="30"
WidthRequest="30">
<Image.GestureRecognizers>
<TapGestureRecognizer BindingContext="{Binding Source={x:Reference MailBoxPage}}" Command="{Binding ChatTappedCommand}"
CommandParameter="{Binding MTRID}" />
<!--Command="{Binding Source={x:Reference Name=nameYourPage}, Path=BindingContext. EditarEnderecoCommand}" CommandParameter="{Binding CliEndCep}"
Command="{Binding ChatTappedCommand}"
CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}"-->
</Image.GestureRecognizers>
</Image>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>`enter code here`
</ContentPage.Content>
//ViewModel:
using MTR.Models.Interface;
using MTR.Views;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Windows.Input;
using Xamarin.Forms;
namespace MTR.ViewModels
{
public class MailBoxPageViewModel : BindableObject
{
private ObservableCollection<MTR.Models.DbModel.Mail> mailedAcceptedList;
public ObservableCollection<MTR.Models.DbModel.Mail> MailedBoxAcceptedList
{
get => mailedAcceptedList;
set
{
if (value == mailedAcceptedList)
return;
mailedAcceptedList = value;
OnPropertyChanged();
}
}
public ICommand ChatTappedCommand
{
get;
private set;
}
private void ChatTapped(object obj)
{
}
public MailBoxPageViewModel()
{
ChatTappedCommand = new Command(ChatTapped);
MailedBoxAcceptedList = new ObservableCollection<Models.DbModel.Mail>();
}
}
}
Here I am trying to call a Command inside the ViewModel class and also I need to send an Id with this call. (Command, CommandParameter, BindingContext)
<TapGestureRecognizer Command="{Binding Path=BindingContext.ChatTappedCommand, Source={x:Reference Name=MailboxAcceptedList}}"
CommandParameter="{Binding}"/>
I'm using a MVVM-Pattern with a ModelView-First approach. This works fine, so far.
Now I have a UserControl (View) which should display various content depending on a Property located in my ViewModel.
First, I tried to solve the issue with DataTemplates and a DataTemplateSelector (See this tutorial) This was working very well. But I was not happy with the solution, because then I have a class (the overrided DataTemplateSelector) which is not connected to the ViewModel and can't be filled from the model.
So I tried to create a own TemplateSelector which uses a Property from the ViewModel. Unfortunately the DataTrigger is not triggering. The Binding from a CheckBox to the ViewModel is also working but not at the DataTrigger (even the designer can't find this path).
Ok, please have a look at the code:
<UserControl.Resources>
<!--Define Template which is displayed for Users-->
<DataTemplate x:Key="templateUser">
<Image
Name="logo"
Source="blanked out"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</DataTemplate>
<!--Define Template which is displayed for Administrators-->
<DataTemplate x:Key="templateAdmin">
<TextBlock Background="Yellow" Margin="3" Text="YEAH, I'm an Administrator" />
</DataTemplate>
<!--My own TemplateSelectpr-->
<DataTemplate x:Key="myTemplateSelector">
<ContentControl x:Name="DynamicContent" ContentTemplate="{StaticResource templateUser}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsAdministrator}" Value="true">
<Setter TargetName="DynamicContent" Property="ContentTemplate" Value="{StaticResource templateAdmin}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentPresenter ContentTemplate="{StaticResource myTemplateSelector}"/>
</Grid>
Of course, I can seperate the Task in two further contentcontrols, but I don't want to maintain those if same content is intersecting.
So can someone suggest anything?
Best regards, and thanks in advance!
The simpler, the better: use a single template, which includes all the controls you need to show. Then switch their visibility using a binding to your property:
<UserControl.Resources>
<DataTemplate x:Key="myTemplate">
<Grid>
<Grid Visibility="{Binding IsAdministrator, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Content for admin -->
</Grid>
<Grid Visibility="{Binding IsAdministrator, Converter={StaticResource NotBooleanToVisibilityConverter}}">
<!-- Content for user -->
</Grid>
</Grid>
</DataTemplate>
</UserControl.Resources>
<Grid>
<ContentPresenter ContentTemplate="{StaticResource myTemplate}"/>
</Grid>
Answer is to long for comment
Arnaud Weil brought me on the right way:
To access the Property 'IsAdministrator' in ViewModel from the Datatemplate, I gave the UserControl a Name e.g.:
<UserControl
x:Class="blanked out"
x:Name="this"
Used the code from Arnaud with some modifications, to inherit the Binding to the ViewModel from UserControl
<UserControl.Resources>
<BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter"/>
<helper:NotBooleanToVisibilityConverter x:Key="NotBooleanToVisibilityConverter"/>
<DataTemplate x:Key="myTemplate">
<Grid>
<Grid Visibility="{Binding DataContext.IsAdministrator, ElementName=this, Converter={StaticResource BooleanToVisibilityConverter}}">
<!-- Content for admin -->
<TextBlock Background="Yellow" Margin="3" Text="ICH BIN ADMNIN; JUCHUUU" />
</Grid>
<Grid Visibility="{Binding DataContext.IsAdministrator, ElementName=this, Converter={StaticResource NotBooleanToVisibilityConverter}}">
<!-- Content for user -->
<Image
Name="logo"
Source="/blanked out"
HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</Grid>
</DataTemplate>
</UserControl.Resources>
And for the inverted BooleanToVisibilityConverter:
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace blankedout.Helper
{
[ValueConversion(typeof(bool), typeof(Visibility))]
public class NotBooleanToVisibilityConverter:IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var boolValue = (bool)value;
return !boolValue ? Visibility.Visible : Visibility.Hidden;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
}
Thanks once again to Arnaud Weil
Regards