1

ボタンコマンドを「外部」データコンテキストのプロパティにバインドする際に少し問題があります。

下の画像は私が持っているレイアウトを示しています。「クリア」ボタン(赤で囲まれている)のCommandParameterをLocationIdにバインドしようとしています。ItemsControlは、場所のObservableCollectionを繰り返します(場所の定義については、以下を参照してください)。

[クリア]ボタンは基本的に、DataGridをクリアするために、ロケーションに添付されているアドレスを削除しようとしています。そのためには、LocationIdをViewModelに渡す必要があります。

実際のコマンドは完全にトリガーされますが、CommandParameterのバインドは完全に正しくありません。

ページレイアウト

場所と住所の基礎となるクラスは次のとおりです。

class Location 
{   
    int Id;
    ObservableCollection<Address> Addresses;
}

class Address
{
    string AddressText;
}

そして、これが3つの代替試行とエラーメッセージでコメントされたXAMLです。

<ItemsControl ItemsSource="{Binding Locations, Mode=TwoWay}">
  <ItemsControl.ItemsPanel>
    <ItemsPanelTemplate>
      <StackPanel VerticalAlignment="Stretch" />
    </ItemsPanelTemplate>
  </ItemsControl.ItemsPanel>
  <ItemsControl.ItemTemplate>
    <DataTemplate>
      <TextBlock Text="{Binding Id}"/>
      <sdk:DataGrid x:Name="ResponseDataGrid" ItemsSource="{Binding Addresses}">
        <sdk:DataGrid.Columns>
          <sdk:DataGridTextColumn Header="Response" Width="*" Binding="{Binding AddressText}"/>
          <sdk:DataGridTemplateColumn Width="100">
            <sdk:DataGridTemplateColumn.HeaderStyle>
              <Style TargetType="sdk:DataGridColumnHeader">
                <Setter Property="ContentTemplate">
                  <Setter.Value>
                    <DataTemplate>
                      <Button Content="Clear" 
                              Command="{Binding DataContext.ClearLocationCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
                              CommandParameter="{Binding Id, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>
                      <!--System.Windows.Data Error: BindingExpression path error: 'Id' property not found on 'System.Windows.Controls.ItemsControl' -->

                      <!--CommandParameter="{Binding ItemsSource.Id, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>-->
                      <!--System.Windows.Data Error: BindingExpression path error: 'Id' property not found on 'System.Collections.ObjectModel.ObservableCollection`1[UI.Location]' -->

                      <!--This gives me the ID but uses a specific index so only works for the first repeated Location-->
                      <!--CommandParameter="{Binding ItemsSource[0].Id, RelativeSource={RelativeSource AncestorType=ItemsControl}}"/>-->
                    </DataTemplate>
                  </Setter.Value>
                </Setter>
              </Style>
            </sdk:DataGridTemplateColumn.HeaderStyle>
            <sdk:DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                <Button Content="Accept">
                  <i:Interaction.Triggers>
                    <i:EventTrigger EventName="Click">
                      <i:InvokeCommandAction 
                        Command="{Binding DataContext.SelectedAddressCommand , RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
                        CommandParameter="{Binding SelectedItem, RelativeSource={RelativeSource AncestorType=sdk:DataGrid}}"/>
                    </i:EventTrigger>
                  </i:Interaction.Triggers>
                </Button>
              </DataTemplate>
            </sdk:DataGridTemplateColumn.CellTemplate>
          </sdk:DataGridTemplateColumn>
        </sdk:DataGrid.Columns>
      </sdk:DataGrid>
    </DataTemplate>
  </ItemsControl.ItemTemplate>
</ItemsControl>

エラーから、ボタンは繰り返されるLocationオブジェクトを完全に見ることができないようです。場所のコレクションまたは特定のインデックス付けされた場所を見ることができますが、必要な繰り返し生成された場所は見ることができません。

ありがとう!

4

2 に答える 2

1

つまり、ViewModelがあり、ObservableCollection<Location>[クリア]をクリックするObservableCollection<Address>と、指定した場所がクリアされます。

ClearコマンドをLocationクラスに配置してみませんか?このコマンドによってトリガーされるロジックについてはわかりませんが、そうすることで、正しい場所IDプロパティにアクセスできるようになります。

編集:これは私の例です:

クラス

public class Location
{
    public Location(int id, IEnumerable<Address> addresses)
    {
        this.Id = id;
        this.Addresses =new ObservableCollection<Address>(addresses);
        this.ClearLocationCommand = new RelayCommand<int>(e => MessageBox.Show(string.Format("Clear command called on Location {0}", this.Id)));
    }

    public int Id { get; set; }
    public ObservableCollection<Address> Addresses { get; set; }

    public ICommand ClearLocationCommand { get; set; }
}

public class Address
{
    public Address(string text)
    {
        this.AddressText = text;
    }

    public string AddressText { get; set; }
}

public class MainWindowViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public MainWindowViewModel()
    {
        Locations = new ObservableCollection<Location>(new []
            {
                new Location(1, new [] { new Address("A1") }), 
                new Location(2, new [] { new Address("A2"), new Address("A3"), }), 
            });
    }

    public ObservableCollection<Location> Locations { get; set; }

    private void OnPropertyChanged(string porpertyName)
    {
        var e = this.PropertyChanged;
        if (e != null)
        {
            e(this, new PropertyChangedEventArgs(porpertyName));
        }
    }
}

XAML

<Window x:Class="TestBindingButtons.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:TestBindingButtons="clr-namespace:TestBindingButtons" Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <TestBindingButtons:MainWindowViewModel />
</Window.DataContext>
<Grid>
    <ItemsControl ItemsSource="{Binding Locations, Mode=TwoWay}">
        <ItemsControl.ItemsPanel>
            <ItemsPanelTemplate>
                <StackPanel VerticalAlignment="Stretch" />
            </ItemsPanelTemplate>
        </ItemsControl.ItemsPanel>
        <ItemsControl.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Id}"/>
                    <DataGrid x:Name="ResponseDataGrid" ItemsSource="{Binding Addresses}">
                        <DataGrid.Columns>
                            <DataGridTextColumn Header="Response" Width="*" Binding="{Binding AddressText}"/>
                            <DataGridTemplateColumn Width="100">
                                <DataGridTemplateColumn.HeaderStyle>
                                    <Style TargetType="DataGridColumnHeader">
                                        <Setter Property="ContentTemplate">
                                            <Setter.Value>
                                                <DataTemplate>
                                                    <Button Content="Clear"
                                                            Command="{Binding DataContext.ClearLocationCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
                                                            />
                                                </DataTemplate>
                                            </Setter.Value>
                                        </Setter>
                                    </Style>
                                </DataGridTemplateColumn.HeaderStyle>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <Button Content="Accept">

                                        </Button>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
                        </DataGrid.Columns>
                    </DataGrid>
                </StackPanel>                    
            </DataTemplate>
        </ItemsControl.ItemTemplate>
    </ItemsControl>
</Grid>
</Window>

PD:私はRelayCommandの実装を投稿しませんでした、あなた自身のものを使用してください。私はあなたの「sdk」フレームワークを使用せず、単なるマイクロソフトのものを使用しました。

于 2013-01-10T16:00:46.643 に答える
1

ClearLocationCommandプロパティをクラスに移動する場合はLocation、次のバインディングを変更することを忘れないでください。

<Button Content="Clear" 
    Command="{Binding DataContext.ClearLocationCommand, RelativeSource={RelativeSource AncestorType=ItemsControl}}" 
    CommandParameter="{Binding Id, RelativeSource={RelativeSource AncestorType=ItemsControl}}"
    />

に:

<Button Content="Clear" 
    Command="{Binding ClearLocationCommand}" 
    CommandParameter="{Binding Id}"
    />

これは、各外部Locationオブジェクトに独自のクリアDataContextコマンドがあり、そのアイテム行ですでに正しいコマンドを使用しているためです。

于 2013-01-16T09:38:34.173 に答える