我有一个名为“MyType”的类型,我的Pivot的ItemsSource绑定到“myFirstVM”ViewModel中名为“DataSource”的ObservableCollection属性。在“MyType”里面我有属性Title。正如您从我的XAML中看到的,TextBlock绑定到MyProperty。如何让它返回当前项目标题?
所以例如,如果我在第二个PivotItem上,我需要DataSource集合中第二个项目的标题
XAML:
<Grid x:Name="LayoutRoot">
<Pivot Name="myPivot"
SelectedItem="{Binding myFirstVM.SelItem, Mode=TwoWay}"
ItemsSource="{Binding myFirstVM.DataSource}"
ItemTemplate="{Binding myFirstVM.OtherTemplate}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.myFirstVM.MyProperty, ElementName=myPivot}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
</Pivot>
</Grid>
myFirstVM代码:
private ObservableCollection<MyType> _dataSource;
public ObservableCollection<MyType> DataSource
{
get
{
if (this._dataSource == null)
{
this._dataSource = new ObservableCollection<MyType>();
}
return this._dataSource;
}
set { }
}
public string MyProperty
{
get
{
if (null != this.SelItem)
{
return this.SelItem.Title;
}
return "no title";
}
set { }
}
private MyType _selItem;
public MyType SelItem
{
get
{
return _selItem;
}
set
{
_selItem = value;
RaisePropertyChanged("SelItem");
RaisePropertyChanged("MyProperty");
}
}
public ObservableCollection<MyOtherType> OtherDataSource
{
get
{
if (null != this.SelItem)
{
return this.SelItem.OtherCollection;
}
else
{
return new ObservableCollection<MyOtherType>();
}
}
set { }
}
private MyOtherType _selOtherItem;
public MyOtherType SelOtherItem
{
get
{
return _selSegment;
}
set
{
_selSegment = value;
RaisePropertyChanged("SelOtherItem");
RaisePropertyChanged("PartsDataSource");
}
}
public ObservableCollection<MyThirdType> ThirdDataSource
{
get
{
if (null != this.SelOtherItem)
{
return this.SelOtherItem.ThirdCollection;
}
else
{
return new ObservableCollection<MyThirdType>();
}
}
set { }
}
这些是我的DataTemplates,用于内部集合“OtherDataSource”和“ThirdDataSource”,即ListBoxes:
<DataTemplate x:Key="OtherTemplate">
<ListBox DataContext="{Binding Source={StaticResource Locator}}"
ItemsSource="{Binding myFirstVM.OtherDataSource}"
ItemTemplate="{StaticResource ThirdTemplate}"
SelectedItem="{Binding myFirstVM.SelOtherItem, Mode=TwoWay}">
</ListBox>
</DataTemplate>
<DataTemplate x:Key="ThirdTemplate">
<ListBox DataContext="{Binding Source={StaticResource Locator}}"
ItemsSource="{Binding myFirstVM.ThirdDataSource}"
ItemTemplate="{StaticResource FourthTemplate}">
</ListBox>
</DataTemplate>
编辑:我用完整的ViewModel和DataTemplates更新了问题,就像@olite一样。你可以看到这种方法的问题是在第二个和第三个dataTemplate中我有ListBoxes。我正在使用一个ViewModel来处理所有事情。有什么想法吗?
答案 0 :(得分:1)
你需要做一些额外的工作。您的ViewModel当前不知道选择了哪个项目。您可以创建一个名为'SelectedItem'的新属性,并绑定Pivots的SelectedItem值。
然后您可以在代码中访问所选项目。
<Grid x:Name="LayoutRoot">
<Pivot Name="myPivot"
Tag="{Binding}"
SelectedItem="{Binding myFirstVM.SelectedItem}"
ItemsSource="{Binding myFirstVM.DataSource}"
ItemTemplate="{Binding myFirstVM.ViewDataTemplate}">
<Pivot.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding DataContext.myFirstVM.MyProperty, ElementName=myPivot}"/>
</DataTemplate>
</Pivot.HeaderTemplate>
</Pivot>
</Grid>
然后你的VM看起来像:
private ObservableCollection<MyType> _dataSource;
public ObservableCollection<MyType> DataSource
{
get
{
if (this._dataSource == null)
{
this._dataSource = new ObservableCollection<MyType>();
}
return this._dataSource;
}
set { }
}
public string MyProperty
{
get
{
if (this.SelectedItem != null)
{
return this.SelectedItem.Title;
}
else
{
return null;
}
}
}
private MyType _selectedItem;
public MyType SelectedItem
{
get
{
return _selectedItem;
}
set
{
_selectedItem = value;
OnNotifyPropertyChanged("SelectedItem");
OnNotifyPropertyChanged("MyProperty");
}
}
或者,如果您只是想要修改文本以进行演示,并且实际上并不需要VM中的SelectedItem,那么您可以使用@ Jehof的方法 - 但实现执行修复的IValueConvertor。
答案 1 :(得分:0)
这应该可以解决问题
<TextBlock Text="{Binding SelectedItem.Title, ElementName=myPivot}"/>
将Text-Property绑定到Pivot元素的SelectedItem属性。当所选的Pivot项目发生更改时,TextBlock应显示项目的标题。
答案 2 :(得分:0)
这是正确的XAML实现:
SelectedItem="{Binding myFirstVM.SelectedItem, Mode=TwoWay}"
并且在代码后面而不是OnNotifyPropertyChanged中,ViewModel需要继承ViewModelBase,MVVM Light的一部分然后在SelectedItem属性的setter中:
RaisePropertyChanged("SelectedItem");