带有UserControl ItemTemplate的列表框始终显示默认值

时间:2014-02-04 21:20:37

标签: c# wpf user-controls listbox itemtemplate

首先,我有一个试图接受UserControl作为DataTemplate的列表框:

<ListBox VerticalAlignment="Stretch" Name="GeneralMcmView" Grid.Column="0"       HorizontalAlignment="Stretch" >
   <ListBox.ItemTemplate>
      <DataTemplate DataType="local:GeneralMcmMessage">
        <local:GeneralMcmMessage />
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

usercontrol的内容如下:

<ContentControl FontFamily="Segoe UI" VerticalAlignment="Stretch" FontSize="10">
    <Grid VerticalAlignment="Stretch">
        <Grid.RowDefinitions>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" Grid.Row="0">
            <TextBlock Name="MessageDateTime" Text="{Binding ElementName=_this, Path=TimeStamp, StringFormat=MM/dd/yyyy h:mm:ss.fff tt \'GMT\' (zzz)}" />
            <TextBlock Name="MessageTypeLabel" Margin="15,0,5,0" Text="Type:"/>
            <TextBlock Name="MessageType" Text="{Binding ElementName=_this, Path=Type}" />
        </StackPanel>
        <StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" Grid.Row="1">
            <TextBlock Name="MessageNameLabel" Margin="0,0,5,0" Text="Message Name:" />
            <TextBlock Name="MessageNameValue" Text="{Binding ElementName=_this, Path=MessageName}" TextWrapping="Wrap" />
        </StackPanel>
        <StackPanel VerticalAlignment="Stretch" Orientation="Vertical" Grid.Row="2">
            <TextBlock Name="MessageLabel" Text="Message:"/>
            <TextBlock Name="Message" Margin="10,0,0,0" Text="{Binding ElementName=_this, Path=MessageContent}" />
        </StackPanel>
    </Grid>
</ContentControl>

然后我创建了一些消息,所有消息都有不同的数据(Listbox的ItemSource绑定到GeneralMessages ObservableCollection):

GeneralMcmMessage newMsg = new GeneralMcmMessage()
        {
            MessageId = e.McmMessageViewInfo.Id,
            TimeStamp = e.McmMessageViewInfo.MessageDateTime,
            Type = e.McmMessageViewInfo.MessageType.ToString(),
            MessageName = e.McmMessageViewInfo.MessageName,
            MessageContent = e.McmMessageViewInfo.Message.ToString()
        };

        GeneralMessages.Add( newMsg );

在运行时我询问列表框的Items属性并且所有数据看起来都是正确的,但是我在列表框中看到的只是具有默认数据值的GeneralMcmMessage用户控件的条目。关于为什么的任何想法?

另外,FWIW我在usercontrol类中使用了INotifyPropertyChanged:

public partial class GeneralMcmMessage : UserControl, INotifyPropertyChanged
{
    private Constants.PiuModule piuModule = Constants.PiuModule.MCM;
    private string className = "GeneralMcmMessage";

    /// <summary>
    /// Event for notifying listeners that a property changed.  Part of   INotifyPropertyChanged
    /// </summary>
    public event PropertyChangedEventHandler PropertyChanged;

    public int MessageId { get; set; }

    private DateTime timeStamp;
    public DateTime TimeStamp
    {
        get
        {
            return timeStamp;
        }
        set
        {
            timeStamp = value;

            OnNotifyPropertyChanged( "TimeStamp" );
        }
    }

2 个答案:

答案 0 :(得分:0)

您说要显示GeneralMcmMessage的DataTemplate是要实例化新的GeneralMcmMessage

  <DataTemplate DataType="local:GeneralMcmMessage">
    <local:GeneralMcmMessage />
  </DataTemplate>

我建议您不要创建UserControl的集合来代替模型对象的集合,而是绑定到UserControl中的属性。

无论哪种方式 - 您在代码中创建的对象将是您在XAML中创建的对象的DataContext,因此删除ElementName=_this应该适当地绑定。请在UserControl中尝试这个简化的XAML。

                                 

<StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" Grid.Row="0">
  <TextBlock Name="MessageDateTime" Text="{Binding TimeStamp, StringFormat=MM/dd/yyyy h:mm:ss.fff tt \'GMT\' (zzz)}" />
  <TextBlock Name="MessageTypeLabel" Margin="15,0,5,0" Text="Type:"/>
  <TextBlock Name="MessageType" Text="{Binding Type}" />
</StackPanel>
<StackPanel VerticalAlignment="Stretch" Orientation="Horizontal" Grid.Row="1">
  <TextBlock Name="MessageNameLabel" Margin="0,0,5,0" Text="Message Name:" />
  <TextBlock Name="MessageNameValue" Text="{Binding MessageName}" TextWrapping="Wrap" />
</StackPanel>
<StackPanel VerticalAlignment="Stretch" Orientation="Vertical" Grid.Row="2">
  <TextBlock Name="MessageLabel" Text="Message:"/>
  <TextBlock Name="Message" Margin="10,0,0,0" Text="{Binding MessageContent}" />
</StackPanel>

答案 1 :(得分:0)

您不发布GeneralMcmMessage的所有代码,因此我不知道您是否在用户控件中设置DataContext,例如在GeneralMcmMessage的构造函数中。

我试过复制你的问题。

用户控制后面的GeneralMcmMessage代码

   public partial class GeneralMcmMessage : UserControl, INotifyPropertyChanged
    {
        private int _messageId;

        public int MessageId
        {
            get
            {
                return _messageId;
            }

            set
            {
                _messageId = value;
                OnPropertyChanged("MessageId");
            }
        }

        private DateTime _timeStamp;

        public DateTime TimeStamp
        {
            get
            {
                return _timeStamp;
            }

            set
            {
                _timeStamp = value;

                OnPropertyChanged("TimeStamp");
            }
        }

        public GeneralMcmMessage()
        {
            InitializeComponent();

           //don’t set data context here
           //DataContext = this;
        }

    }

用户控制GeneralMcmMessage XAML

<StackPanel>
    <TextBlock Margin="5" FontSize="20"  Text="{Binding Path=MessageId}"/>
    <TextBlock Margin="5" FontSize="20"  Text="{Binding Path=TimeStamp}"/>
</StackPanel>

用户控制GeneralMcmMessage用法

public partial class MainWindow : Window, INotifyPropertyChanged
{
    private ObservableCollection<GeneralMcmMessage> _generalMessages;

    public MainWindow()
    {
        InitializeComponent();

        DataContext = this;
    }

    public ObservableCollection<GeneralMcmMessage> GeneralMcmMessages
    {
        get { return _generalMessages; }

        set
        {
            _generalMessages = value;
            OnPropertyChanged("GeneralMcmMessages");
        }
    }


    private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
    {
        GeneralMcmMessages = new ObservableCollection<GeneralMcmMessage>();

        for (int i = 0; i < 10; i++)
        {
            var newMsg = new GeneralMcmMessage
            {
                MessageId = i,
                TimeStamp = DateTime.Now,
            };

            GeneralMcmMessages.Add(newMsg);
        }
    }

}

用户控制GeneralMcmMessage用法XAML

<ListBox x:Name="ListBox"
         Margin="5"
         ItemsSource="{Binding Path=GeneralMcmMessages}">
    <ListBox.ItemTemplate>
        <DataTemplate DataType="stackoverflow:GeneralMcmMessage">
            <stackoverflow:GeneralMcmMessage/>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

如果这不能解决您的问题,请发布所有GeneralMcmMessage吗?

如果您愿意,我可以为您上传示例项目。

谢谢