我正在將應用程序(從Windows窗體和VB.Net轉換爲WPF)進行更新,以向用戶顯示最近消息的列表。我創建了一個MessageViewModel
,一個MessagesListViewModel
和兩個自定義用戶控件MessageListUserControl
和MessageUserControl
。在ItemsControl中將視圖模型綁定到自定義用戶控件
消息在垂直堆棧面板中使用MessageListUserControl
中的ItemsControl
列出,並使用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
中的綁定至{Binding /}
如發現here沒有成功,以及設置DataContext={Binding}
。
當我將用於單個消息顯示的模板XAML直接移動到DataTemplate
時,一切正常,但我希望將它分離爲單獨的控件以在其上執行一些額外的邏輯。
UserControls的一般規則:*從不*顯式設置它們的DataContext(就像你在'DataContext =「{Binding Message ...}「'),因爲這會阻止繼承一個DataContext,例如,當你將它放在一個用於ItemControl的ItemTemplate的DataTemplate中時,結果是你的綁定'Message =」{Binding Path =。,Mode = TwoWay} – Clemens
感謝@Clemens現在我已經從'MessageUserControl'中刪除了它,並且使用了WPF Inspector來檢查應用程序,它看起來像'MessageUserControl'的DataContext是null,所以我嘗試設置('DataContext = {Binding}')沒有運氣 - 它仍然是空的! – euantorano
嘗試刪除Content =「{Binding}」!保持其他所有內容不變。還從各個地方刪除Mode = TwoWay,因爲它們根本不需要。 – AnjumSKhan