저는 WPF에 익숙하지 않아 간단한 작업이 될 것이라고 생각했습니다. 즉, 프로그램 중에 변경되는 비즈니스 개체의 필드 값을 표시해야합니다. C#에서 TextBox.Text 속성을 수동으로 변경하여 "강제로"강제하는 방법을 알고 있지만 WPF를 배우면서 "올바르게"수행하려고합니다. 즉 데이터 바인딩을 의미합니다.WPF 종속 속성 질문
질문 # 1 : 내가 아는 한, 내 선택은 DependencyProperty를 사용하거나 비즈니스 개체에 INotifyPropertyChanged를 구현하는 것입니다.
질문 # 2 : 여기 내 코드의 제네릭 버전으로 DependencyProperty 경로로 이동하려고 시도했습니다.
마크 업 :
는Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" />
TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Source=myTest, Path=Name, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
코드 숨김 : 나는이 프로그램을 실행하면 아무것도 바인딩 속성 값에도 불구하고, 텍스트 상자에 나타납니다
namespace DependencyTest2
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private int i;
private TestSphere myTest;
public MainWindow()
{
InitializeComponent();
i = 0;
myTest = new TestSphere();
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
switch (i)
{
case 0:
myTest.Name = "string1";
break;
case 1:
myTest.Name = "string2";
break;
case 2:
myTest.Name = "string3";
break;
}
i++;
}
}
class TestSphere : DependencyObject
{
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Name", typeof(string), typeof(TestSphere));
public TestSphere()
{
Name = "default";
}
}
}
은 - 뭔가 나는 다른이 원본 값이 변경되었음을 바인딩에 알리는 작업을 수행해야합니까? DependencyProperty를 소스로 사용한다고 생각했지만, 다시 WPF 신인입니다. 감사! 여기
class TestSphere : NotifyProperyChangedBase
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
this.CheckPropertyChanged("Name", ref _Name, ref value);
}
}
public TestSphere()
{
Name = "default";
}
}
public abstract class NotifyProperyChangedBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region methods
protected bool CheckPropertyChanged(string propertyName, ref T oldValue, ref T newValue)
{
if (oldValue == null && newValue == null)
{
return false;
}
if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
{
oldValue = newValue;
FirePropertyChanged(propertyName);
return true;
}
return false;
}
protected void FirePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
너무 내 새로운 마크 업입니다 :
- 스티브는
좋아, 나는 다음과 같이 내가 CodeProject의 발견 래퍼 클래스를 사용에서 INotifyPropertyChanged를 구현하기 위해 노력
Grid Name="myGrid">
Grid.RowDefinitions>
RowDefinition Height="30"/>
RowDefinition Height="30"/>
RowDefinition Height="30"/>
RowDefinition Height="*"/>
/Grid.RowDefinitions>
Label x:Name="myLabel" Grid.Row="0" Foreground="Black" />
Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" />
TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Path=myTest.Name}"/>
/Grid>
또한 'public MainWi'에 myGrid.DataContext = myTest;
행을 추가했습니다. myTest를 인스턴스화 한 직후에 ndow()를 호출합니다. 결과 프로그램을 단계별로 실행하면 this.PropertyChanged
값은 항상 null
으로 평가되므로 PropertyChanged가 실행되지 않습니다. 정말로 멍청한 질문 일 것임에 틀림없는 것을 미리 미안.
- 스티브
업데이트마다 tyChanged()도 두 번. –
둘째, 귀하의 {바인딩}이 어떻게 보이는지 보여 줄 수 있습니까? TextBox의 부모 컨테이너가이고 myGrid.DataContext = myTest 인 경우 바인딩은 이제 {Binding Path = Name}이됩니다. –
잡는 것에 감사드립니다! 원본으로 다시 되돌려 놓는 것을 잊었습니다. 위의 편집을 참조하십시오. – seveland