2012-10-05 2 views
0

나는 UserControl의 데이터를 채우는 IPluginsProvider 인터페이스가있는 MVVM 프랙티스를 사용하여 작성한 ActionsTreeView라는 UserControl을 가지고 있습니다. 이 IContentProvider 인터페이스를 구현하는 개체를 매개 변수로 제공하여 UserControl의 ViewModel을 초기화 할 수 있어야합니다.(MVVM을 사용하여) WPF에서 UserControl에 초기화 매개 변수를 전달하는 방법 (MVVM 사용)

지금까지는 내 접근 방식이 작동하지 않습니다. 나는 올바른 길을 가고 있는지 궁금합니다. 이 사용자 컨트롤을 인스턴스화 할 내 mainWindow 볼 수 내 사용자 정의 컨트롤에서 DependencyProperty 선언합니다. 이 코드는 ViewModel을 빌드하는 데 필요한 UserControl에 PluginsProvider 객체를 전달하려고 시도합니다.

내 내 PropertyChanged 핸들러는 항상 MainWindow.xaml.cs를의 null 때문에 내 UserControl을 나의 PluginProvider DependencyProperty 세터가 나는 코드 권리가 있다고 생각하지만, 나는 바른 길과 내가를하지 않도록 아래로 갈거야 명중 결코 극복

이 연결을 위해 실종 되었습니까? MainWindow.xaml 내 UserControl을 사용

ActionsTreeView.xaml.cs

public partial class ActionsTreeView: UserControl 
{ 
    public static readonly DependencyProperty PluginProviderProperty = DependencyProperty.Register("PluginProvider", typeof(Models.IPluginsProvider), typeof(ActionsTreeView), new FrameworkPropertyMetadata(null, OnPluginProviderChanged)); 

    private ViewModels.ActionsTreeViewModel vm; 

    public ActionsTreeView() 
    { 
     //Wire-up our ViewModel with the data provider and bind it to DataContext for our user control 
     //This is a Mock-up until I figure out a way to get the real provider here 

     Models.IPluginProvider pluginSource = new Models.MockPluginProvider(); 

     vm = new ViewModels.ActionsTreeViewModel(pluginSource); 
     this.DataContext = vm; 

     InitializeComponent(); 
    } 

    private static void OnPluginProviderChanged(DependencyObject source, DependencyPropertyChangedEventArgs e) 
    { 
     ((ActionsTreeView)source).PluginProvider = (Models.IPluginsProvider)e.NewValue; 
    } 

    public Models.IPluginsProvider PluginProvider 
    { 
     get 
     { 
      return (Models.IPluginsProvider)GetValue(PluginProviderProperty); 
     } 

     set 
     { 
      SetValue(PluginProviderProperty, value); 
      vm.SetPluginSource(PluginProvider); 
     } 
    }... 

MainWindow.xaml.cs를

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    public MainWindow() 
    { 
     InitializeComponent(); 

     this.ActionProvider = new Models.PluginsProvider(Library.Action.AvailableActions); 
    } 

    private Models.IPluginsProvider _actionProvider; 
    public Models.IPluginsProvider ActionProvider 
    { 
     get { return _actionProvider; } 
     set 
     { 
      _actionProvider = value; 
      OnPropertyChanged("ActionProvider"); 
     } 
    } 
    protected void OnPropertyChanged(string property) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (handler != null) //HANDLER IS ALWAYS NULL 
     { 
      handler(this, new PropertyChangedEventArgs(property)); 
     } 
    } 
} 

<Grid> 

    <UserControls:ActionsTreeView PluginProvider="{Binding ActionProvider}" /> 

</Grid> 

답변

1

나는 당신이 통과 할 수 있다고 생각하지 않습니다 xaml의 ctor에있는 매개 변수.

당신이 ctor에의 매개 변수 (파람의 PARAM)이이 MVVM 모델에 적합하지만

뒤에 일반 코드에서 많이 사용하는 경우

확실하지를 전달할 수 있습니다 뒤에 당신은 코드에서 컨트롤을 만드는 경우 당신이 당신의 재산 012 이후 바인딩 소스

<Grid> 
    <UserControls:ActionsTreeView PluginProvider="{Binding ActionProvider, RelativeSource={RelativeSource FindAncestor, AncestorType=Window}}" /> 
</Grid> 

누락과 같은 UserControl을

+0

데이터 속성을 설정하는 공용 속성도 사용할 수 있습니다. – CRice

0

을 놓을 곳의 XAML에서 프레임을 사용 보인다은 MainWindow에 선언되어 있기 때문에 바인딩하는 동안 창에서 데이터 컨텍스트로 설정하지 않으면 동일한 소스를 참조해야합니다. 위의 다른 방법으로 다음과 같이 할 수 있습니다. MainWindow를 다음 당신은 당신이 PluginProvider="{Binding ActionProvider}"

public MainWindow() 
{ 
    InitializeComponent(); 

    this.ActionProvider = new Models.PluginsProvider(Library.Action.AvailableActions); 
    DataContext = this; 
} 

내가 설정 한이 바인딩 원본을 사용할 수있는 DataContext 효과적으로 인스턴스에서 바인딩에 ActionProvider의 가치를 해결할 수 thisthis

추가

당신은 또한 부동산 통지 할 수있는 이미 DependencyObject과 같은 MainWindow에서 INotifyPropertyChanged을 제거하기 위해 선택하고 DependencyProperty 그래서 ActionProvider

예를 들어

public Models.IPluginsProvider ActionProvider 
    { 
     get { return (Models.IPluginsProvider)GetValue(ActionProviderProperty); } 
     set { SetValue(ActionProviderProperty, value); } 
    } 

    // Using a DependencyProperty as the backing store for ActionProvider. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty ActionProviderProperty = 
     DependencyProperty.Register("ActionProvider", typeof(Models.IPluginsProvider), typeof(MainWindow), new PropertyMetadata(null)); 

에 대한 그렇지 선언 할 수있다 수동으로 알림 변경을 걱정해야 할 필요가있는 경우 위의 해결책이 도움이되지 않으면 사용하는 것이 좋을 수 있습니다.