2014-09-02 1 views
0

버튼을 클릭하면 파일을 새 위치로 복사하고 파일을 변환 한 다음 새 파일을 원래 위치로 다시 복사하는 등의 간단한 단계를 실행하는 간단한 WPF 응용 프로그램을 만듭니다. .WPF 창을 비동기 적으로 업데이트하십시오.

단계는 정상적으로 작동하지만 WPF 창 업데이트를 통해 단계가 설정되어 있고 실행되는 동안 단추를 숨기고 싶습니다.

창이 내 코드 실행을 마친 후에 만 ​​업데이트됩니다. 나는 me.refresh으로 고전적인 형식으로 이것을 할 수 있었지만 WPF에서는 작동하지 않는다고 생각합니다.

각 단계가 완료된 후에 창을 업데이트 할 수 있습니까?

Button1.Visibility = Windows.Visibility.Hidden 

FileCopy("C:\Test.xsf", AppPath & "\Convert\test.xsf") 
Image7.Visibility = Windows.Visibility.Hidden 
Image3.Visibility = Windows.Visibility.Visible 

Program.StartInfo.FileName = xDefs 
Program.StartInfo.Arguments = "/q" 
Program.Start() 
Program.WaitForExit() 
Image5.Visibility = Windows.Visibility.Visible 

FileCopy("AppPath & "\Convert\test.csv, "C:\Test.csv") 
Button1.Visibility = Windows.Visibility.Visible 
+0

[데이터 바인딩 (WPF)] (http://msdn.microsoft.com/en-us/library/ms750612(v=vs.110) .aspx)이 당신이 찾고있는 것입니다. – pushpraj

+0

코드 예제가 도움이 될 것입니다. MVVM 패턴 뒤에서 또는 코드를 따르는 코드에서 처리하는 중이라면 적어도 알려줄 수 있습니까? – kidshaw

답변

0

프로그램이 바쁜 동안 UI를 업데이트하기 위해, 당신은 UI 메시지 큐에 귀하의 업데이트 요청을 추가 할 Dispatcher class를 사용해야합니다 감사합니다. 이 동기 예를 보자

public void DoWorkWithFile(string filePath) 
{ 
    CopyFile(filePath); 
    ConvertFile(filePath); 
    CopyFileBack(); 
} 

우리는 이것을 휴식 및 작업 사이의 UI에 다시 메시지를 공급하기 위해 Dispatcher 클래스를 사용할 수 있습니다

public void DoWorkWithFile(string filePath) 
{ 
    CopyFile(filePath); 
    RunOnUiThread((Action)delegate { SomeUiTextBlock.Text = "Copied" }); 
    ConvertFile(filePath); 
    RunOnUiThread((Action)delegate { SomeUiTextBlock.Text = "Converted" }); 
    CopyFileBack(); 
    RunOnUiThread((Action)delegate { SomeUiTextBlock.Text = "Copied back" }); 
} 

private object RunOnUiThread(Action method) 
{ 
    return Dispatcher.Invoke(DispatcherPriority.Normal, method); 
} 
0

을 나는 이것이 VB.NET 질문 태그 알고 C# 솔루션을 공유하겠습니다. VB로 이식하는 방법을 충분히 알기를 바랍니다. 이것은 처음이자 stackoverflow에 무엇이든지 게시합니다. 문제가 해결되면 답변으로 표시하십시오 :-)

데이터 바인딩에 대해 실제로 두 가지 이상을 알아야합니다. 당신은 기본적으로 뷰 모델을 만들고, 시간에 따라 변하는 속성을 정의하고이를 창에 바인딩합니다. 이 경우 현재 작업을 추적하고 버튼을 제어 할 수 있도록 값을 정의해야합니다.

면책 조항, 메모장에서 이것을 작성했으며 Visual Studio에서 테스트하지 않았습니다. 오타가있는 지 확인하십시오.

using System.ComponentModel; 

namespace FileConverter 
{ 

    //define the various states the application will transition to 
    public enum OperationStatus 
    { 
     CopyingFileToNewLocation 
     ConvertingFile, 
     CopyingFileToOriginalLocation 
     OperationCompelete 
    } 

    //Defines the view model that shall be bound to the window. 
    //The view model updates the UI using event notifications. Any control that had enabled 
    //binding will get updated automatically 
    public class ViewModel : INotifyPropertyChanged//This interface defines an event used to raise an event and notify subscribers of a changed in data 
    { 
     private OperationStatus _FileConvertionStatus; 
     public event PropertyChangedEventHandler PropertyChanged; 
     public OperationStatus FileConvertionStatus 
     { 
      get 
      { 
       return _FileConvertionStatus; 
      } 
      set 
      { 
       _FileConvertionStatus=value; 
       //Notify all UIElements/objects that had subscribed to this property that it has changed 
       RaisePropertyChanged(this,"FileConvertionStatus"); 
      } 
     } 

     public void RaisePropertyChanged(object sender,string propertyName) 
     { 
      //check if there is any object that had subscribed to changes of any of the data properties in the view model 
      if(PropertyChanged!=null) 
       PropertyChanged(sender,new PropertyChangedEventArgs(propertyName)); 

     } 

     public void StartFileConvertion(string filePath) 
     { 
      //Any time we change the property 'FileConvertionStatus', an event is raised which updates the UI 
      this.FileConvertionStatus=OperationStatus.CopyingFileToNewLocation; 
      StartCopyingToNewLocation(); //call your copying logic 

      this.FileConvertionStatus=OperationStatus.ConvertingFile; 
      StartFileConvertion(); //call your conversion logic 

      this.FileConvertionStatus=OperationStatus.CopyingFileToOriginalLocation(); 
      CopyFileToOriginalLocation(); //... 

      this.FileConvertionStatus=OperationStatus.OperationCompelete; 
     } 

    } 
} 

것은 // 이제 윈도우의 생성자에서 UI 부분 를 들어,이 창은

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 
     ViewModel vm=new ViewModel(); 

     //setting the data context property the window implicitly binds the whole window to our view model object 
     this.DataContext=vm; 

     string filePath="c:\file.txt"; 

     //start the file manipulation process 
     vm.StartFileConvertion(filePath); 
    } 
} 

// 다음 단계를 초기화 된 직후 뷰 모델에 창을 바인드해야합니다 뷰 모델에있는 'FileConvertionStatus'속성에 버튼을 바인딩해야합니다. 버튼을 전체보기 모델에 바인딩하지 않고 관심있는 속성 만 표시합니다. 앞의 코드에서 창을 뷰 모델에 바인딩하면 모든 자식 요소가이 뷰 모델의 공용 속성에 액세스합니다. (VM 지금부터). 이름 = "btnStartFileProcessing" "{FileConvertionStatus 바인딩}"= 사용 ...

우리는 거의 다 : 우리는 ..Button는 X XAML

에 바인딩 특성을한다. 하나가 빠졌어요. 'Enabled'속성은 부울 값임을 알 수 있습니다. 'FileConvertionStatus'속성은 enum입니다. 열거 형을 부울에 직접 할당 할 수없는 것과 같은 방식으로 변환을 수행해야합니다. 이 변환기에서 들어오는 곳입니다.

변환기를 사용하면 XAML에서 하나의 속성을 다른 속성으로 변환하는 방법을 정의 할 수 있습니다.이 경우에는 파일 변환이 성공했을 때만 단추를 사용할 수 있습니다. 이 부분을 읽어보십시오. 아래와 같이

클래스 생성 :

using System.Windows.Data; 
namespace FileConverter 
{ 
    public class OperationStatusToBooleanConverter : IValueConverter 
    { 
     public object Convert(object value, Type targetType,object parameter,System.Globalization.CultureInfo culture) 
     { 
      OperationStatus status=(OperationStatus)value; 
      switch(status) 
      { 
       case OperationStatus.OperationCompelete: 
        return true; //enable the button when everything has been done 
       default: 
        return false;//disable the button as the file processing is underway 
      } 
     } 

     public object ConvertBack(object value, Type targetType,object parameter,System.Globalization.CultureInfo culture) 
     { 
      throw new NotImplementedException(); 
     } 
    } 
} 

다음 단계는 XAML 코드 변환기를 정의하는 것이다. 이것이 더 이상 사실 일 수는 없지만 이것을 초기화하는 것으로 생각하십시오 :-). 그 네임 스페이스를 xaml로 가져 오는 것보다 많습니다. 아래 코드를 App.XAML 파일에 입력하십시오. App.XAML 파일에서 이러한 선언을하면 코드가 전역으로 표시됩니다.

의 xmlns : MyConverters = "CLR 네임 스페이스 : FileConverter의"에 Application.Resources XAML 태그

, 가 상기 바인딩 코드를 재실행

<Application.Resources> 
    <MyConverters:OperationStatusToBooleanConverter x:Key="OperationStatusToBooleanConverter"/> 
</Application.Resources> 

마지막 단계는 다음과 같이 변환 선언 버튼에는 변환기가 포함됩니다.

... 버튼을 사용 = "{FileConvertionStatus 바인딩, 변환기 = {정적 리소스 OperationStatusToBooleanConverter}}"X : 이름 = "btnStartFileProcessing"...

이 코드를 최적화 된 스레드되지 않았 음을 유의하시기 바랍니다 주요 문제는 작업이 오래 걸리는 경우 윈도우가 멈추는 UI 스레드에서 모든 작업이 완료되고 있다는 것입니다.

MVVM 코드 표준에 따라 바인딩을 올바르게 설정하는 데 필요한 작업량이 많습니다. 과도한 살인과 같은 것처럼 보일 수도 있고 때로는 실제로 그렇습니다. UI를 복잡하게 만들면 염두에 두십시오. MVVM은 관심사와 바인딩 전략의 분리로 인해 당일을 확실히 저장합니다.

관련 문제