0

データ テンプレート内でデータをバインドする最善の方法について、何年にもわたって多くの質問が寄せられてきましたが、ベスト プラクティスはありますか? この場合、現在選択されている MemoryListItem TextBox のテキストを MemoryCopyBtn にコピーして、ViewModel で作業できるようにします。

Findname を使用して ListView を見つけることができますが、PageLoad の ListViewItem には null が表示されます。

すべてをメモリ モデル ページに入れることができますが、それはベスト プラクティスではないと思います。

ビジュアル コード ツリーをたどるにはさまざまなオプションがあることがわかりますが、実行時にこれを実行したいのですが、それが本当に唯一の方法ですか?

私のオプションは何ですか?ありがとうございました。

<ListView x:Name="ClipboardList"
                      xmlns:m="using:QuickieEdit.Models"
                      ItemsSource="{x:Bind ViewModel.MemoryItems}">
                <ListView.ItemTemplate>
                    <DataTemplate x:DataType="m:MemoryItem">
                            <StackPanel Orientation="Horizontal">
                                <Button x:Name="MemoryCopyBtn"
                                             Content="Copy"
                                             Click="How to Copy currently selected
                                             MemoryListItem.Text?"/> 
                                <TextBox x:Name="MemoryListItem"
                                               Text="{x:Bind Memory, Mode=TwoWay}">
                               </TextBox>                                  
                           </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
</ListView>
4

3 に答える 3

1

で Button の Click イベントをバインドするとMemoryItem、このイベントでクリックされたボタンのデータ コンテキストを取得できると思います。

テスト用に、ここに非常に簡単なデモを書きました。

<ListView x:Name="ClipboardList" ItemsSource="{x:Bind ViewModel.MemoryItems}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:MemoryItem">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="MemoryCopyBtn"
                                     Content="Copy"
                                     Click="{x:Bind MemoryCopyBtn_Click}" />
                <TextBox x:Name="MemoryListItem"
                                       Text="{x:Bind Memory, Mode=TwoWay}">
                </TextBox>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

コードビハインド:

private MainPageViewModel ViewModel;

public MainPage()
{
    this.InitializeComponent();
    ViewModel = new MainPageViewModel();
}

私の MainPageViewModel クラス:

public class MainPageViewModel
{
    public ObservableCollection<MemoryItem> MemoryItems;

    public MainPageViewModel()
    {
        MemoryItems = new ObservableCollection<MemoryItem>();
        MemoryItems.Clear();
        MemoryItems.Add(new MemoryItem { Memory = "Item 1" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 2" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 3" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 4" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 5" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 6" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 7" });
        MemoryItems.Add(new MemoryItem { Memory = "Item 8" });
    }
}

MemoryItem クラス:

public class MemoryItem
{
    public string Memory { get; set; }

    public void MemoryCopyBtn_Click(object sender, RoutedEventArgs e)
    {
        var item = ((FrameworkElement)e.OriginalSource).DataContext as MemoryItem;
        var text = item.Memory;
    }
}

ここにあるこのコードは、あなたのものと 100% 同じではありません。テストのためだけに非常に単純です。気にしないでください。一般的なケースでは、VisualTree Helper を使用してこの作業を行うことは避けます。x:Bind はイベントに使用できます。ここでは非常に便利です。

于 2016-04-22T06:49:19.487 に答える
1

私があなたを正しく理解していれば、選択した\フォーカスされたテキストボックスではなく、クリックしたボタンと一緒にあるテキストボックスのテキストをコピーしたいのです(そうでなければ、リストビューの各アイテムにコピーボタンがあるため、意味がありません)。その場合は、次のコマンドを使用してください。

    <ListView.ItemTemplate>
        <DataTemplate x:DataType="m:MemoryItem">
            <StackPanel Orientation="Horizontal">
                <Button x:Name="MemoryCopyBtn"
                        Content="Copy"
                        Command="{Binding CopyCommand}"
                        CommandParameter="{Binding ElementName=MemoryListItem, Path=Text}" />
                <TextBox x:Name="MemoryListItem"
                         Text="{x:Bind Memory, Mode=TwoWay}"></TextBox>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>

そしてあなたのMemoryItemで:

public class MemoryItem {
    public MemoryItem() {
        CopyCommand = new RelayCommand(Copy);
    }        

    public string Memory { get; set; }
    public ICommand CopyCommand { get; private set; }

    private void Copy(object argument)
    {
        var text = (string)argument;
        Console.WriteLine(text);
    }
}
于 2016-04-22T05:58:59.053 に答える
0

x:Bind のみを使用する場合は、XAML で Click イベントを定義することをお勧めしますClick="onButtonClicked"。ビューでは、ViewModel を呼び出します (MVVM では、View は VM を認識します)、またはメッセージを発行することができます。ViewModel はそれをキャッチして作業を行います。MVVM Light には、この Messenger メカニズムがあります。

于 2016-04-21T21:01:38.967 に答える