【问题标题】:Data binding for data template does not work .net 4.0 but works 4.5数据模板的数据绑定在 .net 4.0 中不起作用,但在 4.5 中起作用
【发布时间】: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


【解决方案1】:

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

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

【讨论】:

    猜你喜欢
    • 2011-11-21
    • 2019-05-06
    • 1970-01-01
    • 1970-01-01
    • 2015-10-14
    • 2014-12-16
    • 2016-09-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多