2012-05-02 4 views
2

바인딩 할 수있는 "ClearCommand"ICommand 종속성 속성이있는 몇 가지 사용자 지정 컨트롤 (UserControl이 아님)을 만들었습니다. 이 속성은 소리 나는대로 정확하게 처리합니다. 컨트롤 (텍스트 상자 등)의 모든 값을 지 웁니다. 또한 아래에서 설명하는 VM에 동일한 속성 중 일부 (일부)를 바인딩합니다.MVVM을 사용하는 WPF의 ViewModel에서 명령 트리거

은 내가보기에 몇 이러한 컨트롤을 추가 한 :

지금 나는 다음과 같은 MVVM 시나리오에서 이러한 컨트롤에 ClearCommand을 트리거하기 위해 노력하고 붙어있어. 보기에는 내 ViewModel의 SaveCommandDelegateCommand 속성에 바인딩되는 "저장"버튼도 있습니다.

내가해야 할 일은 성공적인 저장시 VM이보기에있는 해당 컨트롤에서 ClearCommand을 트리거해야한다는 것입니다. enter image description here

나는 아래의 코드 예제를 추가 한

UPDATE. ExampleCustomControl과 유사한 몇 가지 컨트롤이 있습니다. 또한 메모하기 만하면 완전히 해제 된 경우 일부를 재구성 할 수 있습니다.

예 제어 니펫을 :

public class ExampleCustomControl : Control { 

    public string SearchTextBox { get; set; } 
    public IEnumerable<CustomObject> ResultList { get; set; } 

    public ExampleCustomControl() { 
     ClearCommand = new DelegateCommand(Clear); 
    } 

    /// <summary> 
    /// Dependency Property for Datagrid ItemSource. 
    /// </summary> 
    public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", 
     typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject))); 

    public CustomObject SelectedItem { 
     get { return (CustomObject)GetValue(SelectedCustomObjectProperty); } 
     set { SetValue(SelectedCustomObjectProperty, value); } 
    } 

    public static DependencyProperty ClearCommandProperty = DependencyProperty.Register("ClearCommand", typeof(ICommand), 
      typeof(ExampleCustomControl), new PropertyMetadata(default(ICommand))); 

    /// <summary> 
    /// Dependency Property for resetting the control 
    /// </summary> 
    [Description("The command that clears the control"), Category("Common Properties")] 
    public ICommand ClearCommand { 
     get { return (ICommand)GetValue(ClearCommandProperty); } 
     set { SetValue(ClearCommandProperty, value); } 
    } 

    public void Clear(object o) { 
     SearchTextBox = string.Empty; 
     SelectedItem = null; 
     ResultList = null; 
    } 
} 

예보기 미리보기 :

<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="*" /> 
     <RowDefinition Height="30"/> 
    </Grid.RowDefinitions> 
    <control:ExampleCustomControl Grid.Row="0" 
     SelectedItem="{Binding Selection, UpdateSourceTrigger=PropertyChanged}" /> 
    <Button Grid.Row="1" x:Name="ResetButton" Command="{Binding SaveCommand}"> 
     Save 
    </Button> 
</Grid> 

예 뷰 모델 :이 잘못된 길에 대해 생각처럼 소리

public class TestViewModel : WorkspaceTask { 
    public TestViewModel() { 
     View = new TestView { Model = this }; 
     SaveCommand = new DelegateCommand(Save); 
    } 

    private CustomObject _selection; 
    public CustomObject Selection { 
     get { return _selection; } 
     set { 
      _selection = value; 
      OnPropertyChanged("Selection"); 
     } 
    } 

    public DelegateCommand SaveCommand { get; private set; } 
    private void Save(object o) { 
     // perform save 
     // clear controls 
    } 
} 
+0

일반적으로 내 명령은 내 ViewModel에 있습니다. ViewModel에서, 당신은'MyCommand.Execute();'를 호출 할 수있다. 그것이 프로젝트 구조화가 아니라면 명확히 할 수있는 코드를 게시하십시오. – cadrell0

+0

빠른 해결 방법으로 SelectedIOtemProperty를 등록 할 때 콜백에서 PropertyMetadata에 PropertyChangedCallback을 설정하고 원하는 모든 항목을 지울 수 있습니다. 그러나 나는 당신의 셋업을 재구성하고 모든 바인딩 된 프로퍼티와 함께 ​​VM에 명확한 정보를 넣는 것에 대해 생각해 보라고 권하고 싶습니다. – HAdes

+0

ExampleCustomControl의 모든 속성을 뷰 모델에 바인딩하면 내 문제가 재사용됩니다. 검색 로직/etc를 사용자 정의 컨트롤에두고 싶습니다. 몇 가지 다른보기에서 동일한 컨트롤을 재사용 할 수 있기를 원합니다. – Alex

답변

2

다른 사람들은 VMVM에서 직접 뷰에 대해 알지 않아야한다고 말했기 때문에 VM이 모든 것을 지우는 사용자 지정 컨트롤에서 무언가를 트리거한다는 것은 실제로 이해가 가지 않습니다.

사용자 정의 컨트롤의 DataContext을 모두 지우려는 모든 속성을 가진 개체로 설정했을 것입니다. 모든 개체는 텍스트 상자 등으로 바인딩됩니다 (양방향). 그런 다음 Save() 메서드 (사용자 지정 컨트롤 DataContext에 바인딩 된) 새 개체를 설정할 수 있으며 개체에 INotifyPropertyChanged을 구현했다고 가정하면 모든 속성이 지워집니다.

내 의견에 따라 경찰 (검증되지 않은 BTW) 현재 설정에 대한 해결 방법의 예를 참조하십시오 :

는 업데이트]

public static DependencyProperty SelectedItemProperty = DependencyProperty.Register("SelectedItem", 
     typeof(CustomObject), typeof(ExampleCustomControl), new PropertyMetadata(default(CustomObject), OnSelectedItemChanged)); 


    private static void OnSelectedItemChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     var cont = source as ExampleCustomControl; 

      //do all the clearing of txtboxes etc here.... 
     cont.SearchTextBox = string.Empty; 
    } 

하지만 난 여전히 시도하고 VM에 모든 이동합니다. 즉, save 명령을 사용하고 텍스트 상자 텍스트 등을 VM의 속성에 바인딩하는 것처럼 명령을 지우면 명령이 호출되면 모든 내용이 지워지고 VM의 Save 메서드에서 쉽게 호출 할 수 있습니다. 하지만 분명히 당신이 장기적으로 달성하려고하는 방법이나 selectedItem 및 textboxes 등이 관련되어 있는지 전혀 알지 못해서 (항상 그렇듯이) 나는 그렇게 생각합니다.

+0

SearchTextBox가 정적으로 입력되지 않기 때문에 제안 된 솔루션이 작동하지 않습니다. – Alex

+1

DependencyObject를 사용하고 ExampleCustomControl에 캐스트하면 내 업데이트 된 답변을 참조하십시오. – HAdes

+0

ExampleCustomControl을 View/ViewModel로 구현하여 컨트롤 (및 포함 된 검색 기능)을 쉽게 재사용하고 내 TestViewModel 내에서 SelectedItem? – Alex

1

합니다. MVVM에서 ViewModel은 사용자 정의 컨트롤에 대해 전혀 알지 못합니다. 따라서이 Clear 기능에 문제가 있습니다.

귀하의 요구 사항이 조금 애매하지만, 당신은 생각했다 :

1) 속성이 VM에서 바인딩하는 경우 컨트롤이 변경 될 때 감지 할 수 없습니다?

2) XAML 레이어에서 Clear를 호출하고 순수한 MVVM으로 유지하려는 경우 Expression Blend SDK의 CallMethodAction과 같은 것을 고려하십시오.

+0

# 1 :이 시나리오를 고려했습니다. 사용자 지정 컨트롤에는 검색 텍스트 상자와 결과를 표시하는 DataGrid가 있습니다. 검색 할 모든 로직은 컨트롤 구현 자체 내에 포함됩니다. 컨트롤의 DataGrid의 선택된 값은 실제로 VM에서 바인드하는 의존적 인 속성입니다. VM 내에서 선택한 값을 재설정 할 수는 있지만 사용자 정의 컨트롤에서 나머지 컨트롤을 재설정하려면 어떻게해야합니까? – Alex

+1

Alex- 추가 도움을 얻기 위해 샘플 코드를 약간 줄여야한다고 생각합니다. 코드 샘플보다 뛰어난 것은 없습니다. – RichardOD

+0

DependencyProperty에서 이벤트를 트리거 할 수있는 동안 해당 이벤트를 정적 범위에 포함시켜야한다는 내용을 설명합니다. 이 컨트롤의 비 정적으로 범위가 지정된 속성을 다시 설정하려면 작동하지 않습니다. – Alex

0

내 의견에 대한 후속 조치로. 귀하의 명령이보기를 타겟팅하고 TextBox을 직접 지우고있는 것으로 의심됩니다. 대신 명령이 ViewModel을 대상으로하고 뷰가 바인딩 된 속성을 지우십시오. 그런 다음 명령을 ViewModel의 속성으로 사용하여 필요할 때마다 호출 할 수 있습니다.

관련 문제