1

まず、私は初心者のプログラマーであり、すべての助けに感謝します。私は現在、ラベルを持つユーザーコントロールと、ウェルカムビューから選択されたボタンに基づいて更新できるコンテンツコントロールが必要なwpfアプリケーションに取り組んでいます。そのようです

<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>

コードビハインド:

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));
        }   
    }
}
4

2 に答える 2

1

さて、ここにいくつかの WPF、バインディング、および Mvvm の間違いがあります...まず、なぜこれを行うのですか?

MainPanel.Content = this.MainPanel.Content;

それは次と同じです:

MainPanel.Content = 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 から始めるのに役立つことを願っています。それは素晴らしいプラットフォームです。

于 2012-09-21T18:07:52.543 に答える
0

わかった。あなたが修正できる間違い:

  • コード ビハインドで MainPanel.Content を変更しないでください。バインディングを通じてViewModelで変更されるはずです。
  • Window.Resources で、DataContext を WelcomeView の MainViewModel に設定していることに注意してください。WelcomeView では、それを WelcomeIewModel にする必要があります。そのようには機能しません。DataCONtext=WelcomeViewModel は Window.Resources によってオーバーライドされます
  • WelcomeViewModel で新しい MainViewmodel を作成するのはなぜですか?
  • View(その特定のMainiewMOdelインスタンス)で使用していないため、PropertyChangedはnullです。それにバインドする場合、PropertyChanged は新しいイベント リスナーを受け取り、null にはなりません。

問題をもう少し詳しく説明していただければ、さらに詳しい情報を提供できます。

于 2012-09-21T18:02:55.473 に答える