【问题标题】:xamarin.forms listview 4 columns get column tappedxamarin.forms listview 4列被点击列
【发布时间】:2019-10-17 16:53:34
【问题描述】:

我有一个普通的 XAML 页面,其中包含一个具有 4 列的 ListView。 首先,我创建一个定义列的网格,例如:

<Grid x:Name="gFirst" BackgroundColor="#4682B4">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="10"/>
                    <ColumnDefinition Width="6*"/>
                    <ColumnDefinition Width="2*"/>
                    <ColumnDefinition Width="2*"/>
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="60"/>
                </Grid.RowDefinitions>
                <StackLayout x:Name="slImage" Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="0" IsVisible="False">
                    <Label Text="" FontFamily="Trebuchet MS" FontSize="16" TextColor="White"/>
                </StackLayout>
                <StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="1" Grid.Row="0">
                    <Label Text="Mieter / Strasse" FontFamily="Trebuchet MS" FontSize="16" Margin="20,0,0,0" TextColor="White"/>
                </StackLayout>
                <StackLayout Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="2" Grid.Row="0">
                    <Label Text="Vertragsbeginn" FontFamily="Trebuchet MS" FontSize="16" TextColor="White"/>
                </StackLayout>
                <StackLayout x:Name="sl3" Orientation="Horizontal" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="3" Grid.Row="0" IsVisible="False">
                    <Label Text="Vertragsende" FontFamily="Trebuchet MS" FontSize="16" TextColor="White"/>
                </StackLayout>
            </Grid>

然后我有一个 ListView:

<ListView x:Name="lv" RowHeight="70">  
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Appearing="ViewCell_Appearing">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="{Binding ColumnWidthImg}" />
                                    <ColumnDefinition Width="{Binding ColumnWidth}" />
                                    <ColumnDefinition Width="{Binding ColumnWidthSec}"/>
                                    <ColumnDefinition Width="{Binding ColumnWidthThird}"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="0" IsVisible="{Binding VisibleColumn}">
                                    <Image Source="{Binding ImgSource}" WidthRequest="30" HeightRequest="30">
                                        <Image.GestureRecognizers>
                                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1" />
                                        </Image.GestureRecognizers>
                                    </Image>
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="1" Grid.Row="0" Margin="20,0,0,0">
                                    <Label Text="{Binding Test1}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                    <Label Text="{Binding Test4}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="2" Grid.Row="0">
                                    <Label Text="{Binding Test2}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="3" Grid.Row="0" IsVisible="{Binding VisibleColumn}">
                                    <Label Text="{Binding Test3}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                            </Grid>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>

我现在的问题是,如何检测列表视图中点击的图像的位置? 使用图像中的点击事件,我无法获得位置。

ListView 中的 ItemTapped 事件给我点击项的对象,但不给我点击的列。

我该如何解决这个问题?

谢谢。

【问题讨论】:

  • 你能解释一下:你的意思是位置:行,网格的列吗?是否触发了图像的点击事件
  • Image 的 Tap 事件被触发了。在这个 Tap 事件中,我想得到,ListView 的哪一行被点击了。
  • 你尝试过 ListView 上的 ItemSelected 事件
  • 是的,但在这个事件中,我不知道点击了哪一列。
  • 问:需要grid.column吗?

标签: listview xamarin.forms multiple-columns


【解决方案1】:

您可以做的是,在所有 4 列中使用按钮而不是标签。 并将每个按钮的命令绑定到视图模型的 4 个不同命令。并且使用按钮的标签属性,您可以绑定模型的 Id,您可以识别用户点击了哪一行。

<?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:custom="clr-namespace:RoundedCornerViewDemo.ControlsToolkit.Custom"
    x:Class="RoundedCornerViewDemo.RoundedCornerViewPage" x:Name="ThisPage">
    <StackLayout Spacing="20" Padding="20,40,20,20" BackgroundColor="LightGray">
        <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>


            <ListView x:Name="lv" RowHeight="70">  
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <ViewCell Appearing="ViewCell_Appearing" Tapped="">
                            <Grid>
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="{Binding ColumnWidthImg}" />
                                    <ColumnDefinition Width="{Binding ColumnWidth}" />
                                    <ColumnDefinition Width="{Binding ColumnWidthSec}"/>
                                    <ColumnDefinition Width="{Binding ColumnWidthThird}"/>
                                </Grid.ColumnDefinitions>
                                <Grid.RowDefinitions>
                                    <RowDefinition Height="*" />
                                </Grid.RowDefinitions>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="0" Grid.Row="0" IsVisible="{Binding VisibleColumn}">
                                    <Image Source="{Binding ImgSource}" WidthRequest="30" HeightRequest="30">
                                        <Image.GestureRecognizers>
                                            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" NumberOfTapsRequired="1" />
                                        </Image.GestureRecognizers>
                                    </Image>
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="1" Grid.Row="0" Margin="20,0,0,0">
                                    <Button Text="{Binding Test1}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" Command="{Binding Path=BindingContext.ButtonCommand, Source={x:Reference Name=ThisPage}}" CommandParameter="{Binding Id}"/>
                                    <Label Text="{Binding Test4}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="2" Grid.Row="0">
                                    <Label Text="{Binding Test2}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                                <StackLayout Orientation="Vertical" VerticalOptions="Center" HorizontalOptions="FillAndExpand" Grid.Column="3" Grid.Row="0" IsVisible="{Binding VisibleColumn}">
                                    <Label Text="{Binding Test3}" FontFamily="Trebuchet MS" FontSize="16" TextColor="Black" />
                                </StackLayout>
                            </Grid>
                        </ViewCell>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
            <Label Text="RoundedCornerView" HorizontalOptions="CenterAndExpand" FontSize="30" TextColor="Blue"/>
         </custom:RoundedCornerView>
        </StackLayout>
</ContentPage>

【讨论】:

【解决方案2】:

是的,您可以将每列的命令绑定到视图模型的 4 个不同命令。 这是来自 acaliaro 的 github 的演示。您可以查看here

虽然它是用 c# 而不是 xaml 编码的,但您可以轻松地将其转换为 Xaml。

主要代码是:

this.BindingContext = new MyPageViewModel();


TapGestureRecognizer tgrTrash = new TapGestureRecognizer();
            tgrTrash.SetBinding(TapGestureRecognizer.CommandProperty, new 
Binding("BindingContext.TrashCommand", source: this));
            tgrTrash.SetBinding(TapGestureRecognizer.CommandParameterProperty, ".");

类 MyPageViewModel (BindingContext)

[ImplementPropertyChanged]
public class MyPageViewModel
{
    bool _isLabelEmptyVisible { get; set; }
    Model _selectedItem { get; set; }
    bool _isTapped { get; set; }
    int _count { get; set; }

    int Count {
        get { return _count; }
        set { _count = value;
            IsListViewVisible = (_count != 0);
            IsLabelEmptyVisible = (_count == 0); }
    }

    public bool IsLabelEmptyVisible { get; set; }
    public bool IsListViewVisible { get; set; }
    public ObservableCollection<Model> List { get; set; } = new ObservableCollection<Model>();

    public MyPageViewModel()
    {

        addRows();

        this.TrashCommand = new Command(async (object obj) => {

            try
            {
                if (_isTapped)
                    return;

                if (obj != null)
                    System.Diagnostics.Debug.WriteLine("Obj is not null");
                else
                    System.Diagnostics.Debug.WriteLine("Obj IS null");


                _isTapped = true;
                var ret = await Application.Current.MainPage.DisplayAlert("Attention", "Delete this row?", "Yes", "No");

                if (ret)
                {

                    //int idx = List.IndexOf((Model)obj);

                    List.Remove((Model)obj);
                    Count = List.Count;
                }

                _isTapped = false;

            }
            catch (Exception ex) {
                _isTapped = false;
                await Application.Current.MainPage.DisplayAlert("Attention", ex.Message, "Ok");
            }
        });             
    }

    private void addRows() {

        List.Add(new Model { Description = "D1", Cost = 10.0, Qty = 1, BackgroundColor = "#9ac16e", TextColor = "#001833" });

    }

    public Model SelectedItem { 
        get { return _selectedItem; }
        set {
            _selectedItem = value;

            if (_selectedItem != null) {

                //Task.Run(async () =>
                //{
                    Device.BeginInvokeOnMainThread(async() =>
                    {
                        var ret = await Application.Current.MainPage.DisplayActionSheet("Select", "Cancel", "Destruction", new string[] { "Edit", "Delete" });


                        if (ret == "Edit")
                        {

                            PromptConfig promptConfig = new PromptConfig();
                            promptConfig.CancelText = "CANCEL";
                            promptConfig.InputType = InputType.Number;
                            promptConfig.Message = "Modify QTA";
                            promptConfig.OkText = "OK";
                            promptConfig.Title = "UPDATE";
                            PromptResult result = await UserDialogs.Instance.PromptAsync(promptConfig);
                            if (result.Ok)
                                SelectedItem.Qty = int.Parse(result.Value);

                        }
                        else if (ret == "Delete")
                        {
                            List.Remove(SelectedItem);
                            Count = List.Count;
                        }
                        else { }
                    });
                //});
            }
        }
    }

    public ICommand TrashCommand { get; protected set;}

}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-11
    • 2018-07-10
    • 1970-01-01
    相关资源
    最近更新 更多