방금 WPF로 시작했지만 여전히 사실에 대한 모든 사실을 갖고 있지 않습니다.WPF에서 데이터 컨트롤 및 멀티 스레딩을 사용하여 기본 UI 업데이트
지금은 데이터 바인딩 및 스레딩을 사용하여 데이터를 업데이트하고이를 시간 기준으로 나타냅니다. 두 개의 텍스트 상자가있는 메인 윈도우와 그것을 클릭하면 실행을 시작하는 스레드로 정의 된 usercontrol이 있습니다. 이 스레드에서 필자는 textboxes, 코드 및 다른 xaml에 바인딩 된 기본 창에서 설정된 2 개의 속성에 대한 호출을합니다.
문제는 코드에 의해 만들어진 데이터 바인딩이 작동하는 반면, xaml로 만든 데이터 바인딩은 텍스트 상자를 직접 업데이트 할 때만 작동한다는 것입니다. 나는 왜 그런지 궁금해했고, 약간의 변화를 통해 작동하도록 만들었지 만,이 솔루션이 "정확하다"는 것은 의심 스럽습니다.
코드
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded" xmlns:my="clr-namespace:WpfApplication1.Elements">
<Grid>
<TextBox Name="Textbox1" Height="23" HorizontalAlignment="Left" Margin="188,50,0,0" VerticalAlignment="Top" Width="120" Background="White" Text="{Binding Source=my:MainWindow, Path=datavalue}" />
<TextBox Name="textBox2" Background="White" Height="23" HorizontalAlignment="Left" Margin="188,101,0,0" Text="{Binding Path=datavalue2, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}} }" VerticalAlignment="Top" Width="120" />
<Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="202,152,0,0" Name="label1" VerticalAlignment="Top" />
<my:Test Margin="81,138,346,92" x:Name="test1" />
</Grid>
</Window>
MainWindow.xaml.cs를
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window, INotifyPropertyChanged
{
public MainWindow()
{
InitializeComponent();
}
public event PropertyChangedEventHandler PropertyChanged;
private int MydataValue;
public int datavalue
{
get
{
return MydataValue;
}
set
{
MydataValue = value;
if (PropertyChanged != null)
{
PropertyChanged(this,
new PropertyChangedEventArgs(
"datavalue"));
}
}
}
private int mydatavalue2;
public int datavalue2
{
get
{
return mydatavalue2;
}
set{
mydatavalue2 = value;
}
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
datavalue2 = 10;
datavalue = 15;
Binding bind = new Binding();
bind.Source = this;
bind.Mode = BindingMode.TwoWay;
bind.Path = new PropertyPath("datavalue");
Textbox1.SetBinding(TextBox.TextProperty, bind);
}
}
}
이
MainWindow.xaml이며 이는 해당 UserControl에게
test.xaml.cs
이다namespace WpfApplication1.Elements
{
/// <summary>
/// Interaction logic for Test.xaml
/// </summary>
public partial class Test : UserControl
{
private Thread t;
private int resolution;
private Stopwatch sw,sw2;
private delegate void changeIconDelegate(long ib);
private ImageBrush b;
private Boolean end=false;
private int count = 0;
public Test()
{
InitializeComponent();
sw = new Stopwatch();
sw2 = new Stopwatch();
b = new ImageBrush();
resolution = 100;
}
private void UserControl_Loaded(object sender, RoutedEventArgs e)
{
b.ImageSource = new BitmapImage(new Uri("pack://application:,,,/DataBinding;component/Images/249137482.png", UriKind.Absolute));
this.Background = b;
}
private void UserControl_MouseUp(object sender, MouseButtonEventArgs e)
{
t = new Thread(new ThreadStart(ThreadTask));
t.Start();
}
private void ThreadTask()
{
while (!end)
{
count = count + 1;
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)delegate()
{
Application.Current.Windows.OfType<MainWindow>().First().datavalue = count;
Application.Current.Windows.OfType<MainWindow>().First().datavalue2 = count;
});
Thread.Sleep((resolution - sw.Elapsed.TotalMilliseconds) > 0 ? TimeSpan.FromMilliseconds(resolution - sw.Elapsed.TotalMilliseconds):TimeSpan.FromMilliseconds(1));
sw.Reset();
sw.Start();
}
}
}
}
컨트롤을 클릭하자마자 응용 프로그램을 시작하면 textbox1이 업데이트되기 시작하지만 textbox2가 직접 변경되면 변경된 알림이 throw되므로 데이터 바인딩이 제대로 수행되고 있습니다. 또는 그렇게 생각합니다.
질문은 다음과 같습니다
-
해당 UserControl의 스레드에서 호출을 직접하지만 수정 한 경우
가 왜 작동합니까? usercontrol은 자식이지만 xaml 파일의 textbox2 선언과 관련이 있다고 생각합니다. 그러나이 방법에 접근하는 방법을 모르겠습니다.
propertychanged 이벤트는 클래스의 모든 속성에 대해 작동하지만 잘못된 값을 사용하고 다른 이벤트에 대해 실수로 멀티 스레드하는 경우에는 불가능합니다.
내가 WPF의 제대로 사양을 사용하지 않는 및 UserControl에서 MainWindow를 호출 할 때 어쩌면 예를 들어, 어떻게든지의 코드에 영향을 미치는 것 확신 : 큰에 대한
죄송 S를 코드와 질문의 양은 WPF를 좋아하기 시작하고 일을하지 않으면 다소 좌절감을 느낍니다. 나는 비슷한 질문을했다. 그러나 메인 UI에서 컨트롤 속성을 업데이트해야 할 때 문제가있는 것을 발견했다. 나 같은 다른 식으로는 안된다.
하는 데 도움이 전혀 놀라운 일이 아니다 희망 당신의 바인더 제본 클래스를 수정할 수 있습니다. 'PropertyChanged' 이벤트를 발생시키는 것은 * 단일 *, * 특정 * 속성이 변경되었고 해당 속성에 대한 바인딩 만 업데이트된다는 것을 소비자에게 알려줍니다. 귀하의 솔루션이 정확합니다. –
예, 문제는 이미 xaml에 경로와 updatesourcetrigger가 있으며 이벤트를 직접 실행하지 않고도 창에서 직접 수정하면 완벽하게 작동한다는 것입니다. 만약 내가 수동으로 이벤트를 해고하지 않는 한 그것을 할 wouldcont 아무것도 usercontrol에서 업데이 트가 – Leucaruth
예 : 귀하의 텍스트 상자 컨트롤이 변경되면, 그것은 바인딩을 업데이 트하려면 알고 있기 때문에 이벤트를 발생시킵니다. 속성이 변경되면 바인딩을 업데이트 할 수 없으므로 이벤트가 발생하지 않았습니다. –