1

LongListSelectorにオブジェクトのリストを表示し、DataTemplateでフォーマットしたいと思います。MVVMを適切に使用するには、このDataTemplateにViewModelを含めたいと思います。

このViewModelの作成は問題ありませんが、ItemをViewModelに渡すにはどうすればよいですか?

私はこのコードを使用しています:

<Controls:LongListSelector 
     ItemsSource="{Binding MyItems}" Margin="0" HorizontalAlignment="Stretch" 
                           HorizontalContentAlignment="Stretch" >
    <Controls:LongListSelector.DataContext>
        <viewmodel:MyListOfItemsViewModel />
    </Controls:LongListSelector.DataContext>
 <Controls:LongListSelector.ItemTemplate>
        <DataTemplate>
            <StackPanel x:Name="CurTemplate">
                <Grid Margin="10" >
                    <Grid.DataContext>
                        <viewmodel:MyViewModel MyItem="{Binding Path=DataContext,ElementName=CurTemplate}" />
                    </Grid.DataContext>

しかし、残念ながら、MyItemに設定されるのは、だけでnullあり、これが実際の値に更新されることはありません。MyItemプロセスの後半で( CurTemplateの初期設定には有効なDataContextがありますが、これはViewModelに送信されないことがわかりました。ここで何かが足りませんか?

完全を期すために、MyViewModelのコードは次のとおりです。

public static DependencyProperty MyItemProperty = DependencyProperty.Register("MyItem", typeof(object), typeof(MyViewModel), new PropertyMetadata("asd", ItemChanged));

    private static void ItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
       System.Diagnostics.Debugger.Break(); // to set when something is set
       // called once, NewValue is null
    }

    public object MyItem
    {
        get
        {
            return (object)GetValue(MyItemProperty);
        }
        set
        {
            SetValue(MyItemProperty, value);
            RaisePropChangeEvent("MyItem");
        }
    }

私は多くの検索といじりをしましたが、これはここで欠けているマイナーなことであると確信しています。ここで私を助けてくれたらとても嬉しいです...

編集:解決済み

{Binding Path=Content,RelativeSource={RelativeSource Mode=TemplatedParent}}ビューモデルのバインディングとして使用することで問題を解決しました。なぜこれがで機能するのかわかりContentませんが、DataContext...では機能しません

あなたの助けに感謝します、robertftw、あなたのリンクされた投稿は私を正しい軌道に乗せました!

4

2 に答える 2

1

私が数日前に抱えていた問題のようです: バインディングはユーザーコントロールプロパティを正しく更新しませんMVVM

public static DependencyProperty MyItemProperty = DependencyProperty.Register("MyItem", typeof(object), typeof(MyViewModel), new PropertyMetadata(string.Empty, ItemChanged));
 private static void ItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
        var obj = d as MyViewModel;
        obj.RaisePropChangeEvent("MyItem");
}

私が抱えていた問題は、 MyItem のセットが実際には呼び出されないことです。

于 2013-01-29T18:27:00.793 に答える
1

あなたは何をしようとしているのですか?選択の変更を操作して、LongListSelector で選択した項目を ViewModel にプッシュしたいだけですか?

もしそうなら... このシナリオでは拡張機能を使用しています。このような拡張機能を持つ唯一のことは、ViewModel からの現在のアイテムの設定がビューに移植されないことです (しかし、それは必要ありませんでした)。

ViewModelの変更は

public RelayCommand<MyItemType> ViewModelCommand

XAMLの変更は

<phone:LongListSelector extensions:LongListSelectorExtension.Command="{Binding ViewModelCommand}" />

拡張子

public static class LongListSelectorExtension
{
public static readonly DependencyProperty CommandProperty =
    DependencyProperty.RegisterAttached("Command",
        typeof(ICommand), typeof(LongListSelectorExtension),
        new PropertyMetadata(null, OnCommandChanged));

public static ICommand GetCommand(LongListSelector selector)
{
    return (ICommand)selector.GetValue(CommandProperty);
}

public static void SetCommand(LongListSelector selector, ICommand value)
{
    selector.SetValue(CommandProperty, value);
}

private static void OnCommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var selector = d as LongListSelector;
    if (selector == null)
    {
        throw new ArgumentException(
            "You must set the Command attached property on an element that derives from LongListSelector.");
    }

    var oldCommand = e.OldValue as ICommand;
    if (oldCommand != null)
    {
        selector.SelectionChanged -= OnSelectionChanged;
    }

    var newCommand = e.NewValue as ICommand;
    if (newCommand != null)
    {
        selector.SelectionChanged += OnSelectionChanged;
    }
}

private static void OnSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    var selector = sender as LongListSelector;
    var command = GetCommand(selector);

    if (command != null && selector.SelectedItem != null)
    {
        command.Execute(selector.SelectedItem);
    }

    selector.SelectedItem = null;
}
}
于 2013-01-30T09:04:42.247 に答える