如何选择使用MVVM图案的LongListSelector一个项目? [英] How to select an item in LongListSelector using the MVVM-pattern?

查看:89
本文介绍了如何选择使用MVVM图案的LongListSelector一个项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用MVVM模式构建应用程序。点击要素之一后,我希望看到这个元素的细节。我写这样的:

XAML

 <电话:LongListSelector的ItemsSource ={绑定数据}
                        保证金=0,0,0,158
                        的SelectedItem ={结合的SelectedItem}>
    <电话:LongListSelector.ItemTemplate>
        <&DataTemplate的GT;
            < StackPanel的方向=横向>
                <按钮和GT;
                <! - 命令={结合ShowDetailsAction} - >
                    < Button.Template>
                        <&控件模板GT;
                            < TextBlock的文本={结合文字}>< / TextBlock的>
                        < /控件模板>
                    < /Button.Template>
                < /按钮>
            < / StackPanel的>
        < / DataTemplate中>
    < /电话:LongListSelector.ItemTemplate>
< /电话:LongListSelector>

视图模型:

 公共IEnumerable的的SelectedItem
{
    {返回_itemsControl; }
    组
    {
        如果(_itemsControl ==值)
            返回;
        _itemsControl =价值;        //测试
        _mss.ErrorNotification(FD);
    }
}

我也尝试过使用命令,没有工作了。

这是命令的一部分:

 公共ICommand的ShowDetailsCommand {搞定;私人集; }公共视图模型()
{
    _loadDataCommand =新DelegateCommand(LoadDataAction);
    SaveChangesCommand =新DelegateCommand(SaveChangesAction);
    ShowDetailsCommand =新DelegateCommand(ShowDetailsAction);
}私人无效ShowDetailsAction(对象P)
{
    _mss.ErrorNotification(喇嘛喇嘛);
}

修改

视图模型

 私人IEnumerable的_itemsControl;
公共IEnumerable的数据
{
  得到
  {
    返回_itemsControl;
  }
  组
  {
    _itemsControl =价值;
    RaisePropertyChanged(数据);
  }
}保护无效RaisePropertyChanged(字符串propertyName的)
{
  PropertyChangedEventHandler处理器=的PropertyChanged;
  如果(处理!= NULL)
    {
      处理器(这一点,新PropertyChangedEventArgs(propertyName的));
    }
}

示范

 公共字符串文本{搞定;组; }
公众的DateTimeOffset数据{搞定;组; }

EDIT2

 私人MobileServiceCollection< ModelAzure,ModelAzure> _items;
        私人只读IMobileServiceTable< ModelAzure> _todoTable = App.MobileService.GetTable< ModelAzure>();
私人异步无效RefreshTodoItems()
{
   尝试
    {
        _items =等待_todoTable.ToCollectionAsync();
    }
   赶上(MobileServiceInvalidOperationException E)
     {
          _mss.ErrorNotification(e.ToString());
     }
   数据= _items;
}


解决方案

数据属性看起来像

 私人MobileServiceCollection< ModelAzure,ModelAzure> _itemsControl;
公共MobileServiceCollection< ModelAzure,ModelAzure>数据
{
  得到
  {
    返回_itemsControl;
  }
  组
  {
    _itemsControl =价值;
    RaisePropertyChanged(数据);
  }
}

编辑

这似乎href=\"http://dotnet-redzone.blogspot.co.uk/2012/11/windows-phone-8longlistselector.html\" rel=\"nofollow\">的SelectedItem从LongListSelector属性不能约束的。
你可以做的可以是:


  • 使用中提供的链接上面,而不是默认的,它看起来像派生的和固定的定制LongListSelector:

     公共类LongListSelector:Microsoft.P​​hone.Controls.LongListSelector
    {
        公共LongListSelector()
        {
            的SelectionChanged + = LongListSelector_SelectionChanged;
        }    无效LongListSelector_SelectionChanged(对象发件人,SelectionChangedEventArgs E)
        {
            的SelectedItem = base.SelectedItem;
        }    公共静态只读的DependencyProperty SelectedItemProperty =
            DependencyProperty.Register(
                的SelectedItem
                typeof运算(对象),
                typeof运算(LongListSelector)
                新PropertyMetadata(NULL,OnSelectedItemChanged)
            );    私有静态无效OnSelectedItemChanged(DependencyObject的D,DependencyPropertyChangedEventArgs E)
        {
            VAR选择=(LongListSelector)D;
            selector.SelectedItem = e.NewValue;
        }    大众新对象的SelectedItem
        {
            {返回的GetValue(SelectedItemProperty); }
            集合{的SetValue(SelectedItemProperty,值); }
        }
    }


  • 注册<一个href=\"http://msdn.microsoft.com/en-us/library/windowsphone/develop/microsoft.phone.controls.longlistselector.selectionchanged%28v=vs.105%29.aspx\"相对=nofollow>从LongListSelector的SelectionChanged 事件,并通过自己打电话给你的视图模型相关的处理程序/回调里面:


在您的视图:

 &LT;电话:LongListSelector X:NAME =YourLongListSelectorName
                        的ItemsSource ={绑定数据}
                        保证金=0,0,0,158
                        的SelectionChanged =OnSelectedItemChanged&GT;

在code背后:

 私人无效OnSelectedItemChanged(对象发件人,SelectionChangedEventArgs selectionChangedEventArgs E)
{
    ((YourViewModel)this.DataContext).NewSelectedItemMethodOrWhateverYouWant((ModelAzure)this.YourLongListSelectorName.SelectedItem);
    //要么
    ((YourViewModel)this.DataContext).SelectedItem =(ModelAzure)this.YourLongListSelectorName.SelectedItem;
}

最后你的按钮命令不能正常工作,因为当你使用的DataTemplate 中,ambiant DataContext的是项目本身。这意味着它在寻找你的命令模式实例,而不是到你的视图模型实例。

希望这有助于

I'm building application using the MVVM pattern. After clicking on one of the elements I want to see this element's details. I wrote this:

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");
    }
}

I tried also using a command, which didn't work, too.

This was the command part:

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");
}

EDIT

ViewModel

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));
    }
}

Model

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

EDIT2

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;
}

解决方案

Your Data property looks like

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

Edited

It seems the SelectedItem property from LongListSelector cannot be bound in WP8. What you can do is either :

  • Use the derived and fixed custom LongListSelector provided in the link above instead of the default one, which looks like :

    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); }
        }
    }
    

  • Register the SelectionChanged event from LongListSelector and call your ViewModel by yourself inside the associated handler/callback :

in your view :

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

in your code behind :

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;
}

Finally your Button command wasn't properly working, because when you use a DataTemplate, the ambiant DataContext is the item itself. Which means that it was looking for your Command into your Model instance, not into your ViewModel instance.

Hope this helps

这篇关于如何选择使用MVVM图案的LongListSelector一个项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆