web-dev-qa-db-ja.com

ListView内のXamarin Forms Buttonコマンドバインディング

私は次の問題を抱えています。私の見解では、リストビューがあります。このリストビューでは、2つのボタンが必要です。 1つはアイテムの編集用、もう1つはアイテムの削除用です。

XAMLのリストビューは次のとおりです

<ListView Grid.Row="1" x:Name="ArbeitsEinträgeList" ItemsSource="{Binding EintragList}" SelectedItem="{Binding SelectedItem}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ViewCell.View>
              <Grid>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Titel}" TextColor="{Binding Fehlerhaft, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="1" Text="{Binding Beginn}" TextColor="{Binding BeginnManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="2" Text="{Binding Ende}" TextColor="{Binding EndeManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Button Grid.Column="3" Command="{Binding EditEintragCommand}" Text="&#xf040;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
                <Button Grid.Column="4" Command="{Binding DeleteEintragCommand}" Text="&#xF00D;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
              </Grid>
            </ViewCell.View>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

ViewModelには必要なものがすべて揃っているので、リストビューにないボタンを使用してコマンドをテストしましたが、完璧に機能します。

バインディングにカーソルを合わせると、「シンボル '...'を解決できません」というメッセージが表示されます

Cannot resolve symbol

20
JanMer

ヤン、

リストビューを使用し、コマンドがDataTemplate内にあるため、バインディングはItemSourceの個々のモデルのバインディングコンテキストにアタッチされます。

これを回避する方法は次のとおりです。

<ListView Grid.Row="1" x:Name="ArbeitsEinträgeList" ItemsSource="{Binding EintragList}" SelectedItem="{Binding SelectedItem}">
      <ListView.ItemTemplate>
        <DataTemplate>
          <ViewCell>
            <ViewCell.View>
              <Grid x:Name="Item">
                <Grid.ColumnDefinitions>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition/>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <Label Text="{Binding Titel}" TextColor="{Binding Fehlerhaft, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="1" Text="{Binding Beginn}" TextColor="{Binding BeginnManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Label Grid.Column="2" Text="{Binding Ende}" TextColor="{Binding EndeManuell, Converter={StaticResource EintragartConverter}}"></Label>
                <Button Grid.Column="3" BindingContext="{Binding Source={x:Reference ArbeitsEinträgeList}, Path=BindingContext}"   Command="{Binding EditEintragCommand}"   CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" Text="&#xf040;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
                <Button Grid.Column="4" BindingContext="{Binding Source={x:Reference ArbeitsEinträgeList}, Path=BindingContext}" Command="{Binding DeleteEintragCommand}"  CommandParameter="{Binding Source={x:Reference Item}, Path=BindingContext}" Text="&#xF00D;" FontFamily="../Ressources/fontawesome.ttf#FontAwesome"></Button>
              </Grid>
            </ViewCell.View>
          </ViewCell>
        </DataTemplate>
      </ListView.ItemTemplate>
    </ListView>

したがって、リストビューのバインディングコンテキスト(つまり、ビューモデルまたは「ArbeitsEinträgeList」)を参照するようにバインディングソースを設定します。コマンドパラメータを個々のアイテムのバインディングコンテキストに設定することもできます。グリッド上のName = "Item"およびCommandParameter = "{Binding Source = {x:Reference Item}、Path = BindingContext}"。

単純に、このようなコマンドを宣言すると、ビューモデルで汎用コマンドを定義し、個々のアイテムのバインドコンテキストであるコマンドパラメーターでコマンドを実行することができます。

 public ICommand DeleteEintragCommand
        {
            get
            {
                return new Command((e) =>
                    {
                        var item = (e as MyModelObject);
                        // delete logic on item
                    });
            }
        }
37
DParry

EintragList-プロパティ内のアイテムにバインドするためです(そのため、BeginnEndeなどのテキストプロパティへのバインドが機能します)。そして、コマンドバインディングは、ビューモデルからではなく、リストから1つのアイテムのコマンドに到達しようとします。

オプション1:アイテムクラスでコマンドを設定し、そこでタップを処理します。

オプション2:バインディングに、ソースがページ(単一のアイテムではなく)であることを伝えます。

Command="{Binding BindingContext.EditEintragCommand, Source={x:Reference Name=MyPageName}}"

ページのルート要素の名前がx:Name="MyPageName"

コマンドを起動するアイテムを知るために、CommandParameterプロパティを設定できます。このプロパティは、コマンドとしてオブジェクトとしても送信されます。

CommandParameter="{Binding .}"

Additionaly:外部テンプレートを使用してリスト内のアイテムを表示する場合、 別の回答で説明したもの (同じ原則)を試すことができます。

12
Joehl

Buttonクリックをバインドする場合は、Button属性でCl​​ickedイベントを使用することもできます。ここに私のコードとその機能があります

  <ListView x:Name="lst1" RowHeight="80">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Orientation="Vertical" Padding="8,0,8,0">
                        <Label Text="{Binding Fname}" TextColor="#000" FontSize="14" LineBreakMode="TailTruncation" />
                        <Label Text="{Binding Mobile}" TextColor="#000" LineBreakMode="TailTruncation" />
                        <Button Text="Remove" Clicked="Delete" CommandParameter="{Binding ID}" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

コード側では、次のような引数を使用してdeleteメソッドを簡単に実装できます

   public void Delete(Object Sender, EventArgs args)
    {
        Button button = (Button)Sender;
        string ID = button.CommandParameter.ToString();
        // Do your Stuff.....
    }
5
Ankit

驚いたことにあなたを捕らえることができる別のものがあります。 ViewModelでICommandをプライベートプロパティとして誤って定義した場合、コマンドへのバインドは発生しません。

0
Blanthor