按照 Josh Smith 的文章在 MVVM 中的 ListView 中添加 ComboBox
我最近开始使用 MVVM 开发 WPF 应用程序。我正在关注 Josh Smith 的文章。我编写了一个基本屏幕,它仅显示 ViewModel 的 ObservableCollection 类中的 ListView 中的数据。它是一个List
。我只是希望能够显示字符串列表,然后能够将其保存回父集合的基础属性中。
我应该使用RelativeSource 与ViewModel 作为DataContext 链接吗?
这是视图模型代码。
public class ViewModel
{
public List<string> AndOrList
{
get
{
List<string> andOrList = new List<string> { "AND", "OR" };
return andOrList;
}
}
public ObservableCollection<BusObjects.Criterion> Criteria
{
get
{
return new ObservableCollection<BusObjects.Criterion>(_stream.ParseFilterCriteria().Criterias);
}
}
}
这是问题区域
<GridViewColumn Header="And / Or">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding AndOrList}">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
这是整个 XAML 代码。我正在尝试将 AndOrList 集合绑定到 ComboBox。
<UserControl.Resources>
<local:FilterCriteriaConverter x:Key="FilterCriteriaConverter"/>
<CollectionViewSource x:Key="CriteriaList"
Source="{Binding Path=Criteria}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="DimName" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style x:Key="CriteriaItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ItemsControl.AlternationIndex" Value="1" />
<Condition Property="IsSelected" Value="False" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#EEEEEEEE" />
</MultiTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView
Name="lstCriteria"
Grid.Row="0"
AlternationCount="2"
DataContext="{StaticResource CriteriaList}"
ItemContainerStyle="{StaticResource CriteriaItemStyle}"
ItemsSource="{Binding}" DockPanel.Dock="Top">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Rectangle Fill="SteelBlue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="And / Or">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding AndOrList}">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=DimName}" />
<GridViewColumn Header="Oprator" DisplayMemberBinding="{Binding Path=Operator}" />
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Path=DimValue}" />
</GridView>
</ListView.View>
</ListView>
<Border Grid.Row="1" CornerRadius="4" BorderThickness="1">
<GridSplitter HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="3"
Background="SteelBlue"/>
</Border>
<Border Name="xmlBorder" Grid.Row="2" VerticalAlignment="Stretch" CornerRadius="4" BorderThickness="1" >
<StackPanel x:Name="stkPanel" Grid.Row="2" Height="Auto" VerticalAlignment="Stretch" >
<XMLViewer:Viewer x:Name="xmlViewer" VerticalAlignment="Stretch" />
<TextBox x:Name="txtXml" TextChanged="XmlTextChanged" Visibility="Hidden"
Text="{Binding Path=FilterCriteria,
Converter={StaticResource FilterCriteriaConverter}}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</Grid>
</DockPanel>
谢谢帕克
I have recently started developing WPF Applications using MVVM. I am following Josh Smith's article. I have written a basic screen which simply displays the data in a ListView from the ViewModel's ObservableCollection class. It's a List<string>
. I just simply want to be able to display the List of strings and than be able to save it back in underlying Property of Parent collection.
Should I be using RelativeSource to link with ViewModel as DataContext?
Here's ViewModel Code.
public class ViewModel
{
public List<string> AndOrList
{
get
{
List<string> andOrList = new List<string> { "AND", "OR" };
return andOrList;
}
}
public ObservableCollection<BusObjects.Criterion> Criteria
{
get
{
return new ObservableCollection<BusObjects.Criterion>(_stream.ParseFilterCriteria().Criterias);
}
}
}
Here's the problem Area
<GridViewColumn Header="And / Or">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding AndOrList}">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Here's the whole XAML Code. I am trying to bind the AndOrList collection to ComboBox.
<UserControl.Resources>
<local:FilterCriteriaConverter x:Key="FilterCriteriaConverter"/>
<CollectionViewSource x:Key="CriteriaList"
Source="{Binding Path=Criteria}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="DimName" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style x:Key="CriteriaItemStyle" TargetType="{x:Type ListViewItem}">
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="ItemsControl.AlternationIndex" Value="1" />
<Condition Property="IsSelected" Value="False" />
<Condition Property="IsMouseOver" Value="False" />
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#EEEEEEEE" />
</MultiTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<DockPanel>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="5"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ListView
Name="lstCriteria"
Grid.Row="0"
AlternationCount="2"
DataContext="{StaticResource CriteriaList}"
ItemContainerStyle="{StaticResource CriteriaItemStyle}"
ItemsSource="{Binding}" DockPanel.Dock="Top">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Rectangle Fill="SteelBlue" VerticalAlignment="Stretch" HorizontalAlignment="Stretch"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="And / Or">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding AndOrList}">
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=DimName}" />
<GridViewColumn Header="Oprator" DisplayMemberBinding="{Binding Path=Operator}" />
<GridViewColumn Header="Value" DisplayMemberBinding="{Binding Path=DimValue}" />
</GridView>
</ListView.View>
</ListView>
<Border Grid.Row="1" CornerRadius="4" BorderThickness="1">
<GridSplitter HorizontalAlignment="Stretch" VerticalAlignment="Center"
Height="3"
Background="SteelBlue"/>
</Border>
<Border Name="xmlBorder" Grid.Row="2" VerticalAlignment="Stretch" CornerRadius="4" BorderThickness="1" >
<StackPanel x:Name="stkPanel" Grid.Row="2" Height="Auto" VerticalAlignment="Stretch" >
<XMLViewer:Viewer x:Name="xmlViewer" VerticalAlignment="Stretch" />
<TextBox x:Name="txtXml" TextChanged="XmlTextChanged" Visibility="Hidden"
Text="{Binding Path=FilterCriteria,
Converter={StaticResource FilterCriteriaConverter}}" TextWrapping="Wrap"/>
</StackPanel>
</Border>
</Grid>
</DockPanel>
Thanks
Pak
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我只需转到
DataContext
仍然是视图模型的位置,将路径更改为DataContext.AndOrList
并添加一个RelativeSource
来查找分别控制。此外,我不会更改 ListView 的 DataContext,只需将所有内容放入 ItemsSource 绑定中:
然后以下操作应该可以工作并且遍历是最少的:
I would just go up to where the
DataContext
is still the view-model, changing the path toDataContext.AndOrList
and adding aRelativeSource
finding the respective control.Further i would not change the DataContext of the ListView, just put everything in the ItemsSource binding:
Then the following should work and the traveral is minimal: