Я получил следующий Xamarin.Forms TemplatedView:Не удается получить InputTransparent работать на пользовательский элемент управления поповер
using System;
using System.Threading.Tasks;
using System.Windows.Input;
using Xamarin.Forms;
namespace STM.Framework.Controls
{
[ContentProperty(nameof(Content))]
public class PopOverLayout : TemplatedView
{
public PopOverLayout()
{
}
#region BoxViewTapCommand
public static BindableProperty BoxViewTapCommandProperty = BindableProperty.Create(nameof(BoxViewTapCommand), typeof(ICommand), typeof(PopOverLayout), default(ICommand), defaultValueCreator: BoxViewTapCommandCreator);
private static object BoxViewTapCommandCreator(BindableObject bindable)
{
return new Command(p => BoxViewTappedExecute(bindable as PopOverLayout, p));
}
private static void BoxViewTappedExecute(PopOverLayout bindable, object parameter)
{
bindable.IsOverlayVisible = !bindable.IsOverlayVisible;
if (!bindable.IsOverlayVisible)
{
bindable.OverlayContent.InputTransparent = true;
}
}
public ICommand BoxViewTapCommand
{
get { return (ICommand) GetValue(BoxViewTapCommandProperty); }
set { SetValue(BoxViewTapCommandProperty, value); }
}
#endregion BoxViewTapCommand
#region OverlayContent
public static BindableProperty OverlayContentProperty = BindableProperty.Create(nameof(OverlayContent), typeof(VisualElement), typeof(PopOverLayout), default(VisualElement));
public VisualElement OverlayContent
{
get { return (VisualElement) GetValue(OverlayContentProperty); }
set { SetValue(OverlayContentProperty, value); }
}
#endregion OverlayContent
#region Content
public static BindableProperty ContentProperty = BindableProperty.Create(nameof(Content), typeof(VisualElement), typeof(PopOverLayout), default(VisualElement));
public VisualElement Content
{
get { return (VisualElement) GetValue(ContentProperty); }
set { SetValue(ContentProperty, value); }
}
#endregion Content
#region IsOverlayVisible
public static BindableProperty IsOverlayVisibleProperty = BindableProperty.Create(nameof(IsOverlayVisible), typeof(bool), typeof(PopOverLayout), default(bool));
public bool IsOverlayVisible
{
get { return (bool) GetValue(IsOverlayVisibleProperty); }
set { SetValue(IsOverlayVisibleProperty, value); }
}
#endregion IsOverlayVisible
}
}
App.xaml:
<Style TargetType="{x:Type controls:PopOverLayout}">
<Setter Property="BackgroundColor" Value="#88000000" />
<Setter Property="IsOverlayVisible" Value="False" />
<Setter Property="ControlTemplate">
<Setter.Value>
<ControlTemplate>
<Grid BackgroundColor="{TemplateBinding BackgroundColor}" >
<Grid.RowDefinitions>
<RowDefinition>
<RowDefinition.Height>
<OnIdiom x:TypeArguments="GridLength" Phone="0" Tablet="50" />
</RowDefinition.Height>
</RowDefinition>
<RowDefinition Height="*" />
<RowDefinition>
<RowDefinition.Height>
<OnIdiom x:TypeArguments="GridLength" Phone="0" Tablet="50" />
</RowDefinition.Height>
</RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Phone="0" Tablet="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
<ColumnDefinition Width="*" />
<ColumnDefinition>
<ColumnDefinition.Width>
<OnIdiom x:TypeArguments="GridLength" Phone="0" Tablet="50" />
</ColumnDefinition.Width>
</ColumnDefinition>
</Grid.ColumnDefinitions>
<controls:EnhancedContentPresenter Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="3"
Content="{TemplateBinding Content}" />
<BoxView Grid.Row="0" Grid.Column="0" Grid.RowSpan="3" Grid.ColumnSpan="3"
InputTransparent="{TemplateBinding IsOverlayVisible, Converter={StaticResource BooleanInversionConverter}, Mode=OneWay}"
IsVisible="{TemplateBinding IsOverlayVisible}"
BackgroundColor="{TemplateBinding BackgroundColor}">
<BoxView.GestureRecognizers>
<TapGestureRecognizer Command="{TemplateBinding BoxViewTapCommand}"></TapGestureRecognizer>
</BoxView.GestureRecognizers>
</BoxView>
<controls:EnhancedContentPresenter Grid.Row="1" Grid.Column="1" Content="{TemplateBinding OverlayContent}"
InputTransparent="{TemplateBinding IsOverlayVisible, Converter={StaticResource BooleanInversionConverter}, Mode=OneWay}"
IsVisible="{TemplateBinding IsOverlayVisible}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Преобразователь:
public class BooleanInversionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(bool))
throw new NotSupportedException();
if (value.GetType() != typeof(bool))
throw new NotSupportedException();
var casted = (bool)value;
return !casted;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
if (targetType != typeof(bool))
throw new NotSupportedException();
if (value.GetType() != typeof(bool))
throw new NotSupportedException();
var casted = (bool)value;
return !casted;
}
}
Контент-центр:
public class EnhancedContentPresenter : ContentPresenter
{
protected override void OnBindingContextChanged()
{
base.OnBindingContextChanged();
if (BindingContext != null && this.Content != null)
SetInheritedBindingContext(this.Content, BindingContext);
}
}
Из-за природы элемента управления довольно очевидно, что я пытаюсь сделать, я думаю: если наложение скрыто, я не хочу, чтобы наложение захватывало события (или другие), а вместо этого вел себя так, как будто даже нет.
Однако я не могу заставить эту работу работать, потому что что-то продолжает захватывать события касания, даже если наложение скрыто, а InputTransparent - true.
Неужели эта проблема звонит кому-нибудь?
Вы уверены, что шаблон связывания работает? Я думал, что нет. – Daniel
@ Daniel В соответствии с отладкой он работает, да – Dbl