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,并且永远不会更新为实际值。我发现在这个过程的后期(在MyItemCurTemplate 的初始设置确实有一个有效的 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

好像我前几天遇到的问题: Binding does not update usercontrol property correct 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 回答