首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >有趣的ContentControl绑定

有趣的ContentControl绑定
EN

Stack Overflow用户
提问于 2012-09-22 01:14:50
回答 2查看 5.1K关注 0票数 1

首先,我应该说我是一个新手程序员,非常感谢大家的帮助。我目前正在开发一个wpf应用程序,在该应用程序中,我希望有一个具有标签和内容控件的用户控件,它可以根据从欢迎视图中选择的按钮进行更新。就像这样

代码语言:javascript
复制
<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>

代码隐藏:

代码语言:javascript
复制
public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        MainPanel.Content = new WelcomeView();
        MainPanel.Content = this.MainPanel.Content;
    }
}

下面是WelcomeViewModel:

代码语言:javascript
复制
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

代码语言:javascript
复制
<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总是空的。

代码语言:javascript
复制
public class BaseViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

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

回答 2

Stack Overflow用户

发布于 2012-09-22 02:07:53

好了,这里有一些WPF、绑定和Mvvm错误...首先,为什么要这样做:

代码语言:javascript
复制
MainPanel.Content = this.MainPanel.Content;

这与以下内容相同:

代码语言:javascript
复制
MainPanel.Content = MainPanel.Content;

这一行很难理解。

你说的第二个原因:

代码语言:javascript
复制
Content="{Binding Path=Content}"

但是你可以在后面的代码中设置:

代码语言:javascript
复制
MainPanel.Content = new WelcomeView();

在这里,您可能有一个概念性错误:当您设置绑定时,默认情况下,此绑定将绑定到控件本身的DataContext (在本例中为UserControl )。好的,为了解决这个问题并使用Mvvm,让我们保持绑定:

代码语言:javascript
复制
Content="{Binding Path=Content}"

但现在我们需要设置UserControl数据上下文:

代码语言:javascript
复制
MainPanel.DataContext = new MainPanelViewModel();

现在我们需要在MainPanelViewModel中创建一个名为Content的属性。在此属性中,您将设置要在ContentControl.Content中显示的内容。(在本例中是WelcomeViewModel和您想要的任何东西)

希望这个答案能帮助你开始使用wpf和mvvm。这是一个很棒的平台。

票数 1
EN

Stack Overflow用户

发布于 2012-09-22 02:02:55

好吧。你可以修正的错误:

  • 不要在代码隐藏中更改MainPanel.Content。它应该在ViewModel中通过绑定进行更改。在您的Window.Resources中,请注意将DataContext设置为MainViewModel of WelcomeView,而在WelcomeView中,您希望将其设置为WelcomeIewModel。它不是那样工作的。是否在WelcomeViewModel?
  • PropertyChanged中创建新的DataCOntext=WelcomeViewModel为空,因为您没有在视图中使用它(特定的MainViewmodel实例),因此该MainViewmodel被MainiewMOdel覆盖。如果您要绑定它,PropertyChanged将接收新的事件侦听器,并且不再为空。

也许可以更好地解释一下你的问题,我可以给你提供更多的信息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12535122

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档