我正在使应用程序(从Windows Forms和VB.Net到WPF)现代化,该应用程序向用户显示最近消息的列表。我创建了MessageViewModel
,MessagesListViewModel
和两个自定义用户控件MessageListUserControl
和MessageUserControl
。
使用ItemsControl
在垂直堆栈面板中的MessageListUserControl
列出消息,并使用MessageuserControl
进行渲染。但是,所有消息都将Message
属性设置为null
,而不是当前消息。
我已经包含在我的代码下面,如果有人对如何修复绑定有任何想法,我将非常感激,因为这是我第一次使用WPF。
的 MessageViewModel 的
using System;
using System.ComponentModel;
namespace TestApp
{
public class MessageViewModel : INotifyPropertyChanged
{
private string _sender;
private string _subject;
private string _content;
public event PropertyChangedEventHandler PropertyChanged;
public string Sender
{
get { return _sender; }
set
{
_sender = value;
NotifyPropertyChanged("Sender");
}
}
public string Subject
{
get { return _subject; }
set
{
_subject = value;
NotifyPropertyChanged("Subject");
}
}
public string Content
{
get { return _content; }
set
{
_content = value.Trim();
NotifyPropertyChanged("Content");
}
}
private void NotifyPropertyChanged(string property)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(property));
}
}
}
}
的 MessageListViewModel 的
using System.Collections.ObjectModel;
namespace TestApp
{
public class MessageListViewModel
{
private readonly ObservableCollection<MessageViewModel> _messages;
public ObservableCollection<MessageViewModel> Messages
{
get { return _messages; }
}
public MessageListViewModel()
{
_messages = new ObservableCollection<MessageViewModel>();
}
#region Methods
public void AddMessage(string sender, string subject, string content)
{
var vm = new MessageViewModel()
{
Sender = sender,
Subject = subject,
Content = content,
};
_messages.Insert(0, vm); // Insert it at the top of the list.
}
#endregion // Methods
}
}
的 MessageUserControl 的
<UserControl x:Class="TestApp.MessageUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TestApp"
mc:Ignorable="d" x:Name="MessageCtrl" Background="White"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<Border BorderThickness="0,0,0,1" BorderBrush="DarkGray" DockPanel.Dock="Top">
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="60"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock Name="lblSender" Text="Sender" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0" FontWeight="Bold" Padding="5"/>
<TextBlock Name="txtSender" Text="{Binding Path=Sender, Mode=TwoWay}" HorizontalAlignment="Stretch" Grid.Row="0" Grid.Column="1" Padding="5"/>
<TextBlock Name="lblSubject" Text="Subject" HorizontalAlignment="Left" Grid.Row="1" Grid.Column="0" FontWeight="Bold" Padding="5"/>
<TextBlock Name="txtSubject" Text="{Binding Path=Subject, Mode=TwoWay}" HorizontalAlignment="Stretch" Grid.Row="1" Grid.Column="1" Padding="5"/>
</Grid>
</Border>
<TextBox BorderThickness="0" Background="Transparent" IsReadOnly="True" Name="txtMessageContent" Text="{Binding Path=Content, Mode=TwoWay}" DockPanel.Dock="Top" Padding="5" VerticalAlignment="Center" HorizontalAlignment="Stretch" TextWrapping="WrapWithOverflow" />
</DockPanel>
</UserControl>
的 MessageListUserControl 的
<UserControl x:Class="TestApp.MessageListUserControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:TestApp"
mc:Ignorable="d" Background="White" x:Name="MessagesListCtrl"
d:DesignHeight="300" d:DesignWidth="300">
<DockPanel>
<ItemsControl x:Name="MessagesStack" Grid.Column="0" ItemsSource="{Binding Path=Messages}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<local:MessageControl Message="{Binding Path=., Mode=TwoWay}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</DockPanel>
</UserControl>
结果最终看起来如下,主题为空,发件人和内容:
我还尝试将DataTemplate
中的MessageListUserControl
中的绑定设置为{Binding /}
here但未成功,并设置DataContext={Binding}
当我将单个消息显示的模板XAML直接移动到DataTemplate
时,一切正常但我希望将它分成一个单独的控件来执行一些额外的逻辑。
答案 0 :(得分:0)
从
中删除Message
属性
<local:MessageControl Message="{Binding Path=., Mode=TwoWay}" />
根本不需要。
从您现在已经完成的DataContext
移除MessageControl
。
一切都保持不变,现在它会起作用。
DataTemplate
会自动将DataContext
设为MessageViewModel
。