【发布时间】:2014-06-11 08:26:07
【问题描述】:
我遇到了一个问题,数据绑定在 .NET Framework 4.0 中不能正常工作,下面是快照,顶部的组合框工作正常,但下面 3 个红色矩形的组合框不能按预期工作(所有组合框都应该显示默认情况下为“B”,就像上面的一样)
以下是打开下拉列表时的快照
但同样的应用程序在安装了 .NET framework 4.5 的机器上可以正常工作,下面是快照
下面是相关源码(项目的目标框架是.NET Framework 4)
文件EnumItem.cs(这个类的目的是支持本地化)
using System;
namespace Test.Enums
{
/// <summary>
/// This class is provide a enum list item.
/// </summary>
/// <typeparam name="T"></typeparam>
public class EnumItem<T> where T : struct
{
public EnumItem(T enumValue)
{
if(!typeof(T).IsEnum)
throw new NotSupportedException("The supported generic type is only enum.");
EnumValue = enumValue;
}
public T EnumValue { get; set; }
public string DisplayString
{ // To make code cleaner, did not get string from resource file
get { return EnumValue.ToString(); }
}
public override string ToString()
{
return DisplayString;
}
}
}
文件 EnumUtil.cs
using System;
using System.Collections.Generic;
namespace Test.Enums
{
public static class EnumUtil<T> where T : struct
{
/// <summary>
/// Traverse all the enum values and encapsulate to a EnumItem list.
/// </summary>
public static List<EnumItem<T>> GetEnumItems()
{
var type = typeof(T);
if (!type.IsEnum)
throw new NotSupportedException("The supported generic type is only enum.");
var enumItems = new List<EnumItem<T>>();
foreach (var val in Enum.GetValues(type))
{
var item = new EnumItem<T>((T)val);
enumItems.Add(item);
}
return enumItems;
}
}
}
文件 VMBase.cs
using System.ComponentModel;
namespace Test.Base
{
/// <summary>
/// The base class for all the view model classes
/// </summary>
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}
文件 MainVM.cs
using System.Collections.ObjectModel;
using Test.Base;
using Test.Enums;
using TestDemo;
namespace ItemTemplate
{
/// <summary>
/// Hardware Series
/// </summary>
public enum HwSeries
{
/// <summary>
/// Series A
/// </summary>
A,
B
}
internal class MainVM : ViewModelBase
{
private HwSeries series_ = HwSeries.B;
public HwSeries Series
{
get { return series_; }
set
{
if (series_ != value)
{
series_ = value;
OnPropertyChanged("Series");
}
}
}
/// <summary>
/// Hardware Series
/// </summary>
public ObservableCollection<EnumItem<HwSeries>> HwSeriesCollection { get; private set; }
private ObservableCollection<SubVM> cascadingList_ = new ObservableCollection<SubVM>();
public MainVM ()
{
Initialize();
}
public void Initialize()
{
HwSeriesCollection = new ObservableCollection<EnumItem<HwSeries>>(
EnumUtil<HwSeries>.GetEnumItems());
for (var pairNumber = 1; pairNumber < 4; pairNumber++)
{
var cascading = new SubVM();
cascadingList_.Add(cascading);
}
}
public ObservableCollection<SubVM> CascadingList
{
get { return cascadingList_; }
}
}
}
文件 SubVM.cs
using System.Collections.ObjectModel;
using ItemTemplate;
using Test.Base;
using Test.Enums;
namespace TestDemo
{
/// <summary>
/// Cascading Plug-in View Model
/// </summary>
public class SubVM : ViewModelBase
{
/// <summary>
/// Hardware Series
/// </summary>
public ObservableCollection<EnumItem<HwSeries>> HwSeriesCollection { get; private set; }
public void InitializeItemSources()
{
HwSeriesCollection = new ObservableCollection<EnumItem<HwSeries>>
(EnumUtil<HwSeries>.GetEnumItems());
}
public SubVM()
{
InitializeItemSources();
}
private HwSeries series_ = HwSeries.B;
public HwSeries Series
{
get { return series_; }
set
{
if (series_ != value)
{
series_ = value;
OnPropertyChanged("Series");
}
}
}
}
}
MainWindow.xaml
<Window x:Class="ItemTemplate.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:testDemo="clr-namespace:TestDemo"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<Style TargetType="{x:Type ComboBox}">
<Setter Property="DisplayMemberPath" Value="DisplayString"/>
<Setter Property="SelectedValuePath" Value="EnumValue"/>
<Setter Property="Margin" Value="0,5,0,5"></Setter>
<Setter Property="Grid.Column" Value="1" />
</Style>
<!-- Default DataTemplate -->
<DataTemplate x:Key="CascadingTemplate" DataType="testDemo:SubVM">
<Grid Name="PairsGrid" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" MinHeight="20"/>
</Grid.RowDefinitions>
<TextBlock Name="SeriesTextBlock" Text="Series (With DataTemplate)"
Grid.Column="0" />
<ComboBox Name="SeriesComboBox" Grid.Column="1"
ItemsSource="{Binding HwSeriesCollection}" SelectedValue="{Binding Series}"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
</Window.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="10*" />
<RowDefinition Height="10*" />
<RowDefinition Height="50*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="201*" />
<ColumnDefinition Width="302*" />
</Grid.ColumnDefinitions>
<TextBlock Name="SeriesTextBlock"
Text="Series (Without DataTemplate)" Grid.Column="0" Grid.Row="0" />
<ComboBox Name="SeriesComboBox"
Grid.Column="1" Grid.Row="0"
ItemsSource="{Binding HwSeriesCollection}"
SelectedValue="{Binding Series}"/>
<ItemsControl
Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
Name="CascadingItemsControl"
ItemsSource="{Binding CascadingList}"
HorizontalAlignment="Stretch"
ItemTemplate="{StaticResource CascadingTemplate}" >
</ItemsControl>
</Grid>
</Window>
MainWindow.cs
namespace ItemTemplate
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainVM();
}
}
}
非常感谢您的帮助!
【问题讨论】:
-
预期的行为是什么?
-
默认情况下所有组合框都应显示“B”@nit
-
在 4.0 和 4.5 上都可以正常工作.. 你能尝试干净构建解决方案吗.. 删除所有临时文件和 obj 文件夹,然后编译并运行
-
你在只安装了 .NET 4(没有安装 .NET 4.5)的机器上试过吗?
-
no..我尝试将目标框架从 4.5 更改为 4
标签: .net wpf data-binding datatemplate