컨트롤에 바인딩하려는 사용자 지정 개체가 있습니다. 해당 사용자 정의 객체에서 INotifyPropertyChanged 인터페이스를 구현했습니다. 내 개체와 그 개체의 속성에 성공적으로 바인딩되었습니다.WPF/XAML에서 INotifyPropertyChanged를 올바르게 사용하는 방법
내가 알 수없는 것은 거기에서 어떻게 가는지입니다. 나는 2 일 동안이 작업을하고 있었지만 아직 작동시키지 못하고있다.
내 가정은 컨트롤에 바인딩 된 속성을 변경하면 해당 속성에 설정된 값이 컨트롤에 나타날 것입니다. 그러나 아무리 많은 속성을 변경하더라도 UI는 초기 값 이상으로 업데이트되지 않습니다. 나는이 방식에서 INotifyPropertyChanged를 구현 한
는 : 는 A base class which implements INotifyPropertyChanged
그래서 내 기본 클래스는 이것이다 :
[Serializable]
public abstract class BindableObject : INotifyPropertyChanged
{
#region Data
private static readonly Dictionary<string, PropertyChangedEventArgs> eventArgCache;
private const string ERROR_MSG = "{0} is not a public property of {1}";
#endregion // Data
#region Constructors
static BindableObject()
{
eventArgCache = new Dictionary<string, PropertyChangedEventArgs>();
}
protected BindableObject()
{
}
#endregion // Constructors
#region Public Members
/// <summary>
/// Raised when a public property of this object is set.
/// </summary>
[field: NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
/// <summary>
/// Returns an instance of PropertyChangedEventArgs for
/// the specified property name.
/// </summary>
/// <param name="propertyName">
/// The name of the property to create event args for.
/// </param>
public static PropertyChangedEventArgs
GetPropertyChangedEventArgs(string propertyName)
{
if (String.IsNullOrEmpty(propertyName))
throw new ArgumentException(
"propertyName cannot be null or empty.");
PropertyChangedEventArgs args;
// Get the event args from the cache, creating them
// and adding to the cache if necessary.
lock (typeof(BindableObject))
{
bool isCached = eventArgCache.ContainsKey(propertyName);
if (!isCached)
{
eventArgCache.Add(
propertyName,
new PropertyChangedEventArgs(propertyName));
}
args = eventArgCache[propertyName];
}
return args;
}
#endregion // Public Members
#region Protected Members
/// <summary>
/// Derived classes can override this method to
/// execute logic after a property is set. The
/// base implementation does nothing.
/// </summary>
/// <param name="propertyName">
/// The property which was changed.
/// </param>
protected virtual void AfterPropertyChanged(string propertyName)
{
}
/// <summary>
/// Attempts to raise the PropertyChanged event, and
/// invokes the virtual AfterPropertyChanged method,
/// regardless of whether the event was raised or not.
/// </summary>
/// <param name="propertyName">
/// The property which was changed.
/// </param>
protected void RaisePropertyChanged(string propertyName)
{
this.VerifyProperty(propertyName);
PropertyChangedEventHandler handler = this.PropertyChanged;
if (handler != null)
{
// Get the cached event args.
PropertyChangedEventArgs args =
GetPropertyChangedEventArgs(propertyName);
// Raise the PropertyChanged event.
handler(this, args);
}
this.AfterPropertyChanged(propertyName);
}
#endregion // Protected Members
#region Private Helpers
[Conditional("DEBUG")]
private void VerifyProperty(string propertyName)
{
Type type = this.GetType();
// Look for a public property with the specified name.
PropertyInfo propInfo = type.GetProperty(propertyName);
if (propInfo == null)
{
// The property could not be found,
// so alert the developer of the problem.
string msg = string.Format(
ERROR_MSG,
propertyName,
type.FullName);
Debug.Fail(msg);
}
}
#endregion // Private Helpers
}
내가 위에 내가 내 재산에 이렇게 내 파생 클래스에서 그 클래스에서 상속 :
public virtual string Name
{
get
{
return m_strName;
}
set
{
m_strName = value;
RaisePropertyChanged("Name");
}
}
내 XAML이 (축약 버전)과 같습니다
<Window x:Class="PSSPECApplication.Windows.Project"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:System="clr-namespace:System;assembly=mscorlib"
DataContext="{Binding SizingProject, RelativeSource={RelativeSource Self}}">
<StackPanel VerticalAlignment="Center">
<TextBox Name="txtProjectName" Text="{Binding Name}" />
</StackPanel>
창의 데이터 컨텍스트가 SizingProject라는 속성임을 알 수 있습니다. SizingProject는 BindableObject에서 파생 된 파생 형식이며 Name 속성이 들어 있으며 PropertyChanged 이벤트 처리기를 발생시킵니다.
내 창 생성자에서 SizingProject를 채우고 Name 속성이 설정됩니다.
테스트하려면이 창에 이름 속성을 원래대로 설정하는 이벤트를 발생시키는 단추가 있어야합니다. 그러나 name 속성이 변경되면 아무 일도 일어나지 않습니다. BindableObject로 추적했고 PropertyChanged 이벤트는 항상 null로 설정되므로 처리기가 설정되고 실행되지 않습니다. 왜 이런거야?
나는 INotifyPropertyChanged를 구현하고 해당 유형의 바인딩을 사용하여 WPF가 해당 이벤트 핸들러를 자동으로 설정 한 다음 올바른 동작이 발생한다고 생각했습니다. 나를 위해, 나는 그 행동을 결코 보지 못한다.
나는이 문제를 파악했다. 내가해야 할 일은 SizingProject 속성에 대한 DependencyProperty를 만드는 것입니다. 내가 그 일을 끝내고 모든 일이 잘 됐어.
public static readonly DependencyProperty SizingProjectProperty =
DependencyProperty.Register("SizingProject", typeof(Sizing.Project), typeof(Project), new UIPropertyMetadata());
public Sizing.Project SizingProject
{
get
{
return (Sizing.Project)GetValue(Project.SizingProjectProperty);
}
set
{
SetValue(Project.SizingProjectProperty, value);
}
}
출력 창에 바인딩 오류가 있습니까? –
대신이 솔루션을 대신 사용해야했습니다. http://www.pochet.net/blog/2010/07/02/inotifypropertychanged-automatic-dependent-property-and-nested-object-support/ – Ristogod