如何选择使用MVVM图案的LongListSelector一个项目? [英] How to select an item in LongListSelector using the MVVM-pattern?
问题描述
我使用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.Phone.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屋!