我在使用Listview时遇到问题,并且几乎要放弃upp。
我在ListView中有一个CustomButton
,OnPressUp
应该触发一个事件。
问题在于,当我touch
按下按钮时,它触发了多个其他按钮的事件。
这是我的代码,请告诉您是否发现奇怪的地方。
XAML
<StackLayout Orientation="Vertical">
<Label Text="Video Properties" Style="{ StaticResource HeaderContainer}"></Label>
<controls:YListView x:Name="lstVideosProperties" OnSelected="LstVideosProperties_OnSelected">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<Grid VerticalOptions="FillAndExpand">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="8*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<Image Aspect="Fill" VerticalOptions="FillAndExpand" Source="{Binding DefaultThumbnailUrl}" Grid.Row="0" Grid.Column="0"></Image>
<Grid Grid.Row="0" Grid.Column="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="7*"></ColumnDefinition>
<ColumnDefinition Width="3*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="4*"></RowDefinition>
<RowDefinition Height="6*"></RowDefinition>
</Grid.RowDefinitions>
<StackLayout Style="{StaticResource FormFloatLeft}" Grid.Row="0" Grid.Column="0">
<Label Text="{Binding Title}" Style="{StaticResource Header}" />
</StackLayout>
<controls:CustomButton Grid.RowSpan="2"
CommandParameter="{Binding VideoId}"
IsEnabled="{Binding VideoId ,Converter={StaticResource Downloadable}}"
Grid.Row="0" Grid.Column="1"
x:Name="_btnDownload"
OnPressUp="_btnDownload_OnPressUp"
Image="download.png"
HorizontalOptions="EndAndExpand"
VerticalOptions="StartAndExpand"
Style="{StaticResource Icon}" />
<StackLayout VerticalOptions="Start" Style="{StaticResource FormFloatLeft}" Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="2">
<Label Text="{Binding Views}" Style="{StaticResource UnderText}" />
</StackLayout>
</Grid>
</Grid>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</controls:YListView>
数据绑定项
lstVideosProperties.ItemsSource = _videos;
自定义按钮
public class CustomButton : Button
{
public CustomButton()
{
ColorBeforeSelection = Color.Transparent;
}
public Color OnPressColor { get; set; } = ((Color)Application.Current.Resources["pressed"]);
private Color ColorBeforeSelection;
public TextAlignment? TextAlignment { get; set; }
public event EventHandler OnPressUp;
public event EventHandler OnPressDown;
public Action<double, double> SizeAllocated;
public bool _isSelected;
public bool IsSelected
{
get { return _isSelected; }
set
{
_isSelected = value;
if (_isSelected)
{
if (this.BackgroundColor != OnPressColor)
ColorBeforeSelection = this.BackgroundColor;
this.BackgroundColor = OnPressColor;
}
else
this.BackgroundColor = ColorBeforeSelection;
}
}
protected override void OnSizeAllocated(double width, double height)
{
base.OnSizeAllocated(width, height);
SizeAllocated?.Invoke(width, height);
}
public void OnPressed()
{
OnPressDown?.Invoke(this, null);
}
public void OnReleased()
{
OnPressUp?.Invoke(this, null);
}
}
CustomButtonRenderer
public class CustomButtonRenderer : ButtonRenderer
{
Context _context;
public CustomButtonRenderer(Context context) : base(context)
{
_context = context;
}
protected override void OnElementChanged(ElementChangedEventArgs<Xamarin.Forms.Button> e)
{
base.OnElementChanged(e);
var customRendererButton = e.NewElement as CustomButton;
var control = Control as Android.Widget.Button;
switch (customRendererButton.TextAlignment)
{
case Xamarin.Forms.TextAlignment.Center:
control.Gravity = GravityFlags.Center | GravityFlags.CenterVertical;
break;
case Xamarin.Forms.TextAlignment.Start:
control.Gravity = GravityFlags.Left | GravityFlags.CenterVertical;
break;
case Xamarin.Forms.TextAlignment.End:
control.Gravity = GravityFlags.End | GravityFlags.CenterVertical;
break;
}
if (!customRendererButton.IsEnabled)
{
control.SetBackgroundColor(new Android.Graphics.Color(
ContextCompat.GetColor(_context, Resource.Color.disabled_background)
));
}
bool selected = customRendererButton.IsSelected;
bool prevent = false;
Timer _timer = null;
control.Touch += (object sender, TouchEventArgs args) =>
{
if (!customRendererButton.IsEnabled)
{
control.SetBackgroundColor(new Android.Graphics.Color(
ContextCompat.GetColor(_context, Resource.Color.disabled_background)
));
return;
}
if (args.Event.Action == MotionEventActions.Up)
{
_timer.Stop();
if (!selected)
customRendererButton.IsSelected = false;
if (!prevent)
customRendererButton.OnReleased();
prevent = false; // reset
return;
}
else if (args.Event.Action == MotionEventActions.Down)
{
_timer?.Stop();
_timer = new Timer(200);
_timer.Elapsed += new ElapsedEventHandler((o, arg) =>
{
if (!selected)
customRendererButton.IsSelected = false;
prevent = true;
});
_timer.Start();
selected = customRendererButton.IsSelected;
if (!customRendererButton.IsSelected)
customRendererButton.IsSelected = true;
customRendererButton.OnPressed();
return;
}
else if (args.Event.Action == MotionEventActions.Move)
{
}
};
}
}
答案 0 :(得分:0)
以这种方式绑定按钮的命令:
Command="{Binding Path=BindingContext.CommandName,Source={x:Reference root}}" CommandParameter="{Binding .}"
在页面的开头括号中将页面名称定义为“ x:Name =“ root””。(名称可以是任意值)