数据模板的数据绑定不起作用.net 4.0但是工作4.5

时间:2014-06-11 08:26:07

标签: .net wpf data-binding datatemplate

我遇到的问题是数据绑定在.NET framework 4.0中无法正常工作,下面是快照,顶部组合框工作正常,但是3个组合框下面的红色矩形不能按预期工作(所有的组合框都应该显示“B”默认情况下,就像顶部的那样)

enter image description here

下面是打开下拉列表时的快照 enter image description here

但是相同的应用程序在安装.NET Framework 4.5的机器上正常工作,下面是快照

enter image description here

以下是相关的源代码(项目的目标框架是.NET Framework 4

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

非常感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

问题通过以下代码更改解决了

<!-- 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" 

                    <!-- Specify this explicitly -->
                    SelectedValuePath="EnumValue"

                    ItemsSource="{Binding HwSeriesCollection}" SelectedValue="{Binding Series}"/>
                </Grid>
            </DataTemplate>