2014-09-19 3 views
0

초보자 질문이지만 작동시키지 못합니다. SO "How Should the View Model Close the form" 에 대한 답을 사용하려고, 난은 UserControl을 함께 정의 :연결된 속성 (MVVM)이있는 모달 대화 상자를 닫을 수 없습니까?

설계 쇼 동안
<UserControl 
     ..... 
     h:DialogCloser.DialogResult="{Binding DialogResult}" 
     > 

:

  public static class DialogCloser 
{ 
    public static readonly DependencyProperty DialogResultProperty = 
     DependencyProperty.RegisterAttached(
      "DialogResult", 
      typeof(bool?), 
      typeof(DialogCloser), 
      new PropertyMetadata(DialogResultChanged)); 

    private static void DialogResultChanged(
     DependencyObject d, 
     DependencyPropertyChangedEventArgs e) 
    { 
     var window = d as Window; 
     if (window != null) 
      window.DialogResult = e.NewValue as bool?; 
    } 
    public static void SetDialogResult(Window target, bool? value) 
    { 
     target.SetValue(DialogResultProperty, value); 
    } 
} 

:

 Property 'DialogResult' is not attachable to elements of type 'UserControl'. 

DialogCloser과 같이 정의된다 UserControl은 다음에 의해 열립니다.

  var win = new WindowDialog(); 
     win.Title = title; 
     win.DataContext = datacontext; 

     return win.ShowDialog(); 
01 UserControl을위한 뷰 모델에서 23,516,

, 나는이 :

public new void DoExit() 
    { 
     DialogResult = true; 
    } 

    private bool? dialogresult; 
    public bool? DialogResult 
    { 
     get 
     { 
      return dialogresult; 
     } 
     set 
     { 
      if (dialogresult != value) 
      { 
       dialogresult = value; 
       OnPropertyChanged("DialogResult"); 
      } 
     } 
    } 

) (DoExit를 사용하여 모달 대화, 내 UserControl을은 하지 가까이 않습니다. 뭐가 문제 야? 디자이너 (VS 2010)에 오류가 발생하지 않도록하려면 어떻게해야합니까?

어떤 도움을 주셔서 감사합니다.

부록 :

public class ModalDialogService : IModalDialogService 
{ 
    public bool? ShowDialog(string title, object datacontext) 
    { 
     var win = new WindowDialog(); 

     win.Title = title; 
     win.DataContext = datacontext; 

     return win.ShowDialog(); 
    } 
} 

참고 : "UserControl을"이 아니라 "윈도우"로했을 경우, 디자이너가 행복하지만, 그 오류는 다음과 같습니다

"Window must be the root of the tree. Cannot add Window as a child of Visual." 

도움말 누군가?

+0

이 코드의 위치는? :'var win = new WindowDialog(); ' – Sheridan

+0

@Sheridan (다른 usercontrol의) 다른 뷰 모델입니다. –

+0

그 코드가있는 경우보기 모델이 아닙니다. 뷰 모델은 '창'과 뷰에 대해 * 아무것도 * 알지 못합니다. 이 경우에는 '보기 모델'이 손상되었으므로 정상적으로 다음과 같이 'Window.Close'를 처리하십시오 : if (win.ShowDialog() == DialogResult.OK) DoSomething(); ' – Sheridan

답변

2

나는 이것에 익숙하지 않지만 모든 것을 모으기 위해, 나는 나 같은 신입생을위한 가능한 대답으로 제안 할 것이다.

최상의 MVVM 방식을 준수합니까? 디자이너가 언급 한 바와 같이

먼저, '재산권'DialogResult를은 '유형'의 UserControl '의 요소에 부착되지

내 번역은. "컨트롤"창이 아닌 - 그래서 닫을 수 없습니다 따라서

h:DialogCloser.DialogResult="{Binding DialogResult}" 

잘못되었습니다. 제거하십시오.

둘째는, 내 UserControl을 지금

<Window x:Class="Nova5.UI.Views.Ink.WindowDialog" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="WindowDialog" 
    WindowStyle="SingleBorderWindow" 
    WindowStartupLocation="CenterOwner" SizeToContent="WidthAndHeight"> 

    <ContentPresenter x:Name="DialogPresenter" Content="{Binding .}"/> 

</Window> 

로 다르게 일반 윈도우의 유일한 요소로 표시되고, 모든 일이 최상위 뷰 모델 그렇게되면 시작

var dialog = new WindowDialog 
      { 
       Title = "It's me Margaret", 
       ShowInTaskbar = false,    
       Topmost = true,      
       ResizeMode = ResizeMode.NoResize  
      }; 
      dialog.Owner = Application.Current.Windows.OfType<Window>().SingleOrDefault(x => x.IsActive); 

      ModalDialogService dialogService = new ModalDialogService(); 

      dialogService.ShowDialog<PrescriptionWriterViewModel>(dialog, 
       new PrescriptionWriterViewModel(), 
       returnedViewModelInstance =>         
        { 
          if (dialog.DialogResult.HasValue && dialog.DialogResult.Value) 
           { 
           } 
        } 
       ); 
     }; 

때 Exit는 뷰 콘트롤에서 DelegateCommand를 통해 수행됩니다.

public new void DoExit() 
    { 
     OnRequestClose(); 
    } 

    public event EventHandler RequestClose; 

    void OnRequestClose() 
    { 
     EventHandler handler = this.RequestClose; 
     if (handler != null) 
     { 
      handler(this, EventArgs.Empty); 
     } 
    } 

다음 시작 대화 서비스에서 처리 닫이 요청은,

뷰가 닫혀
public void ShowDialog<TDialogViewModel>(IModalWindow view, TDialogViewModel viewModel, Action<TDialogViewModel> onDialogClose) 
    { 
     view.DataContext = viewModel; 

     IDialogViewModel vm = viewModel as IDialogViewModel; 
     if (vm !=null) 
      vm.RequestClose += (s,e)=> view.Close();  //RequestClose is the event in the ViewModel that the view will listen for. 

     if (onDialogClose != null) 
     { 
      view.Closed += (sender, e) => onDialogClose(viewModel); 
     }    
     view.Show(); 
    } 

의 onDialogClose (뷰 모델)을 다시 최상위 뷰 모델에 호출하고

로 지정된 조치를 완료
returnedViewModelInstance =>        
        { 
          if (dialog.DialogResult.HasValue && dialog.DialogResult.Value) 
           { 
           } 
        } 

그래서 몇 시간의 학습을 완료했습니다. 나는 그것이 누군가에게 유용하기를 바란다.