繁体   English   中英

如何使用MVVM模式在LongListSelector中选择项目?

[英]How to select an item in LongListSelector using the MVVM-pattern?

我正在使用MVVM模式构建应用程序。 单击其中一个元素后,我想查看该元素的详细信息。 我这样写:

XAML

<phone:LongListSelector ItemsSource="{Binding Data}" 
                        Margin="0,0,0,158"
                        SelectedItem="{Binding SelectedItem}">
    <phone:LongListSelector.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Horizontal">
                <Button>
                <!-- Command="{Binding ShowDetailsAction}"-->
                    <Button.Template>
                        <ControlTemplate>
                            <TextBlock Text="{Binding Text}"></TextBlock>
                        </ControlTemplate>
                    </Button.Template>
                </Button>
            </StackPanel>
        </DataTemplate>
    </phone:LongListSelector.ItemTemplate>
</phone:LongListSelector>

ViewModel:

public IEnumerable SelectedItem
{
    get { return _itemsControl; }
    set
    {
        if (_itemsControl == value)
            return;
        _itemsControl = value;

        // Test
        _mss.ErrorNotification("fd");
    }
}

我也尝试使用一个命令,但该命令也不起作用。

这是命令部分:

public ICommand ShowDetailsCommand { get; private set; }

public ViewModel()
{
    _loadDataCommand = new DelegateCommand(LoadDataAction);
    SaveChangesCommand = new DelegateCommand(SaveChangesAction);
    ShowDetailsCommand = new DelegateCommand(ShowDetailsAction);
}

private void ShowDetailsAction(object p)
{
    _mss.ErrorNotification("bla bla");
}

编辑

视图模型

private IEnumerable _itemsControl;
public IEnumerable Data
{
  get
  {
    return _itemsControl;
  }
  set
  {
    _itemsControl = value;
    RaisePropertyChanged("Data");
  }
}

protected void RaisePropertyChanged(string propertyName)
{
  PropertyChangedEventHandler handler = PropertyChanged;
  if (handler != null)
    {
      handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

模型

public string Text { get; set; }
public DateTimeOffset Data { get; set; }

编辑2

private MobileServiceCollection<ModelAzure, ModelAzure> _items;
        private readonly IMobileServiceTable<ModelAzure> _todoTable = App.MobileService.GetTable<ModelAzure>();


private async void RefreshTodoItems()
{
   try
    {
        _items = await _todoTable.ToCollectionAsync();
    }
   catch (MobileServiceInvalidOperationException e)
     {
          _mss.ErrorNotification(e.ToString());
     }
   Data = _items;
}

在ViewModel中,您具有:

public IEnumerable SelectedItem
{
get { return _itemsControl; }
set
{
    if (_itemsControl == value)
        return;
    _itemsControl = value;

    // Test
    _mss.ErrorNotification("fd");
}

}

为什么您的SelectItem是IEnumerable? 它不应该是“模型”类型的吗? 您的列表绑定到“数据”,该数据应该是ObservableList,而不是IEnumerable。 它将提供自己的更改通知,因此您不需要。

列表将在被选择时设置SelectedItem,但如果类型错误,则不会设置。

格雷格

您的Data属性看起来像

private MobileServiceCollection<ModelAzure, ModelAzure> _itemsControl;
public MobileServiceCollection<ModelAzure, ModelAzure> Data
{
  get
  {
    return _itemsControl;
  }
  set
  {
    _itemsControl = value;
    RaisePropertyChanged("Data");
  }
}

已编辑

看来LongListSelectorSelectedItem属性不能在WP8中绑定 您可以执行以下任一操作:

  • 使用上面链接中提供的派生和固定的自定义LongListSelector,而不是默认的自定义LongListSelector,如下所示:

     public class LongListSelector : Microsoft.Phone.Controls.LongListSelector { public LongListSelector() { SelectionChanged += LongListSelector_SelectionChanged; } void LongListSelector_SelectionChanged(object sender, SelectionChangedEventArgs e) { SelectedItem = base.SelectedItem; } public static readonly DependencyProperty SelectedItemProperty = DependencyProperty.Register( "SelectedItem", typeof(object), typeof(LongListSelector), new PropertyMetadata(null, OnSelectedItemChanged) ); private static void OnSelectedItemChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var selector = (LongListSelector)d; selector.SelectedItem = e.NewValue; } public new object SelectedItem { get { return GetValue(SelectedItemProperty); } set { SetValue(SelectedItemProperty, value); } } } 
  • 从LongListSelector中注册SelectionChanged事件,并在关联的处理程序/回调内部自己调用ViewModel:

在您看来:

<phone:LongListSelector x:Name="YourLongListSelectorName"
                        ItemsSource="{Binding Data}" 
                        Margin="0,0,0,158"
                        SelectionChanged="OnSelectedItemChanged">

在您后面的代码中:

private void OnSelectedItemChanged(object sender, SelectionChangedEventArgs selectionChangedEventArgs e)
{
    ((YourViewModel)this.DataContext).NewSelectedItemMethodOrWhateverYouWant((ModelAzure)this.YourLongListSelectorName.SelectedItem);
    //or
    ((YourViewModel)this.DataContext).SelectedItem = (ModelAzure)this.YourLongListSelectorName.SelectedItem;
}

最终,您的Button命令无法正常工作,因为当您使用DataTemplate ,周围的DataContext就是项本身。 这意味着它是在Model实例而不是ViewModel实例中寻找Command

希望这可以帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM