我以前只是通过将一串字符串转换为一个带有换行符的字符串来创建一段文本。这个绑定工作;当它应该和所有,但我试图将文本列表移动到一个ItemsControl,因为他们将需要在未来的某个点超链接。问题:当PropertyChangeEvent被触发时,ItemsControl不会改变。相关代码如下:ItemsControlSourceSource Binding not updating
的XAML
<local:BaseUserControl x:Class="BAC.Windows.UI.Views.ErrorsView"
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:BAC.Windows.UI.Views"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
...
<ItemsControl ItemsSource="{Binding Path=ErrorMessages}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}"></TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<!--<TextBlock VerticalAlignment="Center" Visibility="{Binding ErrorMessages, Converter={StaticResource VisibleWhenNotEmptyConverter}}" Text="{Binding ErrorMessages, Converter={StaticResource ErrorMessagesToTextConverter}}">
(What I used to use)
</TextBlock>-->
...
</local:BaseUserControl>
视图模型
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using ASI.Core.Core;
using ASI.Core.DTO;
using ASI.Core.Extensions;
using ASI.Core.Mappers;
using BAC.Core.Resources;
using BAC.Core.Services;
using BAC.Core.ViewModels.Views;
namespace BAC.Core.ViewModels
{
public interface IErrorsViewModel : IViewModel<IErrorsView>
{
}
public class ErrorsViewModel : BaseViewModel<IErrorsView>, IErrorsViewModel
{
...
private readonly ErrorDTO _errorDTO;
private readonly ErrorDTO _warningDTO;
public ErrorsViewModel(...) : base(view)
{
...
//Just added this string to know that it's at least binding. This Message displays, and never changes.
ErrorMessages = new List<string>() {"Simple Message"};
//Tells the View to bind dataContext to Viewmodel
Edit();
}
private void errorDTOOnPropertyChanged(object sender, PropertyChangedEventArgs propertyChangedEventArgs)
{
ErrorDTO dto;
if (!string.Equals(propertyChangedEventArgs.PropertyName, nameof(dto.HasError))) return;
ErrorMessages.Clear();
_errorDTO.ErrorMessages.Each(x => ErrorMessages.Add(Constants.Captions.Errors + ": " + x));
_warningDTO.ErrorMessages.Each(x => ErrorMessages.Add(Constants.Captions.Warnings + ": " + x));
OnPropertyChanged(() => ErrorMessages);
OnPropertyChanged(() => HasError);
OnPropertyChanged(() => HasWarning);
}
...
public bool HasError => _errorDTO.HasError;
public bool HasWarning => _warningDTO.HasError;
public IList<string> ErrorMessages { get; set; }
...
}
而只是因为我知道有人会问,看它...
public class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
[NotifyPropertyChangedInvocator]
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public void OnPropertyChanged<T>(Expression<Func<T>> propertyExpression)
{
var body = propertyExpression.Body as MemberExpression;
if (body != null)
OnPropertyChanged(body.Member.Name);
}
protected void OnEvent(Action action)
{
try
{
action();
}
catch
{ }
}
}
我我肯定这简直是一件愚蠢的事情,但我看起来越难,我就越容易被某种简单的东西吓倒。为什么该绑定对于除ItemSource之外的其他所有控件都适用?这有什么特别之处?
非常感谢你,这个解决方案工作。我会记住,ItemSource控件更喜欢未来的Observable Collection。 – Sonic1015