2012-09-21 4 views
1

먼저 내가 초보자 프로그래머라고해야하고 모든 도움을 주시면 감사하겠습니다. 현재 wpf 응용 프로그램에서 나는 어떤 단추가 환영보기에서 선택되었는지에 따라 업데이트 할 수있는 label 및 contentcontrol이있는 usercontrol을 갖고 싶습니다. 같은 BEHIND흥미로운 ContentControl 바인딩

<Window x:Class="ContentControl.Views.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:vm="clr-namespace:ContentControl.ViewModels" 
    xmlns:views="clr-namespace:ContentControl.Views" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <DataTemplate DataType="{x:Type vm:ScreenViewModel}"> 
     <views:ScreenView DataContext="{Binding}"/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type vm:WelcomeViewModel}"> 
     <views:WelcomeView DataContext="{Binding}"/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type vm:MeetingRoomViewModel}"> 
     <views:MeetingRoomView DataContext="{Binding}"/> 
    </DataTemplate> 
    <DataTemplate DataType="{x:Type vm:DashboardViewModel}"> 
     <views:DashboardView /> 
    </DataTemplate> 
</Window.Resources> 

<Grid> 
    <StackPanel> 
     <Label>This Is My Label</Label> 
     <ContentControl x:Name="MainPanel" Content="{Binding Path=Content}" 
      MinHeight="200" 
      MinWidth="200" 
      HorizontalContentAlignment="Left" 
      VerticalContentAlignment="Center" 
      Focusable="False"> 
     </ContentControl> 
    </StackPanel> 
</Grid> 
</Window> 

CODE : 여기

public MainWindow() 
    { 
     InitializeComponent(); 
     DataContext = this; 
     MainPanel.Content = new WelcomeView(); 
     MainPanel.Content = this.MainPanel.Content; 
    } 
} 

는 WelcomeViewModel입니다 :

internal class WelcomeViewModel : BaseViewModel 
{ 
    private MainWindowViewModel _mainWindowVm; 
    private RelayCommand<string> _viewChangedCommand; 

    public ICommand ViewChangedCommand 
    { 
     get { return _viewChangedCommand ?? (_viewChangedCommand = new RelayCommand<string>(OnViewChanged)); } 
    } 

    public event EventHandler ViewChanged; 

    private void OnViewChanged(string view) 
    { 
     EventHandler handler = ViewChanged; 
     if (handler != null) handler(view, EventArgs.Empty); 
    } 

    public MainWindowViewModel MainWindowVm 
    { 
     get { return _mainWindowVm; } 
     set 
     { 
      _mainWindowVm = value; 
      OnPropertyChanged("MainViewModel"); 
     } 
    } 

    public WelcomeViewModel() 
    { 
     MainWindowVm = new MainWindowViewModel(); 
     ViewChanged += MainWindowVm.ViewChanged; 
    } 
} 

그리고 마지막으로 내 welcome.xaml

<UserControl x:Class="ContentControl.Views.WelcomeView" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:vm="clr-namespace:ContentControl.ViewModels" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300"> 
<UserControl.DataContext> 
    <vm:WelcomeViewModel /> 
</UserControl.DataContext> 
<Grid Background="red"> 
    <Grid.RowDefinitions > 
     <RowDefinition Height="25*" /> 
     <RowDefinition Height="50*"/> 
     <RowDefinition Height="25*"/> 
    </Grid.RowDefinitions> 

    <Rectangle Grid.Row="0" Fill="Green"/> 
    <DockPanel Grid.Row="1" HorizontalAlignment="Center" Background="White"> 
     <Button Height="50" Width="50" Margin="5" Content="DASH" Command="{Binding ViewChangedCommand}" CommandParameter="Dashboard"/> 
     <Button Height="50" Width="50" Margin="5" Content="ROOM" Command="{Binding ViewChangedCommand}" CommandParameter="MeetingRoom"/> 
     <Button Height="50" Width="50" Margin="5" Content="SCREEN" Command="{Binding ViewChangedCommand}" CommandParameter="Screen" /> 
    </DockPanel> 
    <Rectangle Grid.Row="2" Fill="Blue"/> 
</Grid> 
</UserControl> 

그래서 문제가 될 때입니다 ViewChange 이벤트가 실행 중지되었습니다. MainWindowViewModel에 표시되지만 PropertyEventHandler (아래 참조)를 사용할 때 PropertyChanged는 항상 null입니다.

public class BaseViewModel : INotifyPropertyChanged 
{ 
    public event PropertyChangedEventHandler PropertyChanged; 

    protected void OnPropertyChanged(string name) 
    { 
     PropertyChangedEventHandler handler = PropertyChanged; 
     if (PropertyChanged != null) 
     { 
      PropertyChanged(this, new PropertyChangedEventArgs(name)); 
     } 
    } 
} 

답변

0

오케이. 수정이 가능한 실수 :

  • 코드 숨김으로 MainPanel.Content를 변경하지 마십시오. 그것은 바인딩을 통해 ViewModel에서 변경되어야합니다.
  • Window.Resources에서 DataContext를 WelcomeView의 MainViewModel로 설정하고 있고, WelcomeView에서 WelcomeIewModel로 설정했는지 확인하십시오. 그것은 그렇게 작동하지 않습니다. DataCOntext = WelcomeViewModel이 Window에 의해 오버라이드됩니다. 리소스
  • 왜 WelcomeViewModel에서 새 MainViewmodel을 만들었습니까?
  • View (특정 MainiewMOdel 인스턴스)에서 사용하지 않기 때문에 PropertyChanged가 null입니다. 만약 당신이 그것에 바인딩하면, PropertyChanged는 새로운 이벤트 리스너를 reciee하고 더 이상 null이되지 않을 것입니다.

아마도 조금 더 나은 문제를 설명하고 추가 정보를 제공 할 수 있습니다.

+0

welcomeView로 초기화하기 위해 코드에서 변경했습니다. ViewChanged 이벤트를 수신 할 수 있도록 환영에서 MainViewModel을 만들었습니다. 'MainWindowVm = 새로운 MainWindowViewModel(); ViewChanged + = MainWindowVm.ViewChanged; ' 특정 인스턴스를 얻으려면 어떻게해야합니까? – KitWat

1

음, 여기에 몇 가지 WPF, 바인딩 및 MVVM 실수를 가지고 ... 첫째, 당신이 할 왜이 :

MainPanel.Content = MainPanel.Content; 

이 :와 동일

MainPanel.Content = this.MainPanel.Content; 

선은 비 전통적이다.

두 번째 이유는 말했다 :

Content="{Binding Path=Content}" 

하지만 당신은 뒤에 코드에서 설정 : 여기

MainPanel.Content = new WelcomeView(); 

당신이 개념 오류가있을 수 있습니다 : 당신은 설정하면 기본이 바인딩의 의지에 의해 바인딩 컨트롤 자체 (이 경우에는 UserControl)의 DataContext를 완료해야합니다. 좋아,이 문제를 해결하고 MVVM와 함께 작동하도록, 바인딩 유지 할 수 있습니다 :

Content="{Binding Path=Content}" 

을하지만 지금 우리가있는 UserControl의 데이터 컨텍스트 설정해야합니다

MainPanel.DataContext = new MainPanelViewModel(); 

을 그리고 지금 우리가 속성을 작성해야 MainPanelViewModel은 Content를 호출했다. 이 속성 안에 ContentControl.Content에 표시 할 내용을 설정합니다. (이 경우 WelcomeViewModel과 원하는 모든 것)

이 답변을 사용하면 wpf 및 mvvm으로 시작하는 데 도움이되기를 바랍니다. 그것은 훌륭한 플랫폼입니다.

+0

주 패널은 콘텐츠 컨트롤의 이름입니다. MainPanel을 다른 뷰의 컨테이너로 만들고 싶습니다. 그러므로 WelcomeView()로 설정하십시오. 그럼 첫 번째 뷰 바운드 (welcomeView)에있는 버튼 선택으로 MainPanel에 다른 뷰에 바인딩 할 수 있기를 원합니다. – KitWat

+0

그런 다음이 뷰를 뷰 모델의 Content 속성에 설정해야합니다. 하지만 뷰 (ViewChangedCommand)를 변경하는 명령도 ViewModel (예 : MainPanelViewModel) 내에 있어야합니다. –

+0

의미가 확실하지 않습니다 – KitWat