在使用Visual Studio的WPF应用程序中,如何将usercontrol绑定到usercontrol变量?

时间:2018-02-21 11:35:28

标签: c# wpf xaml

我不确定我是否正确地提出了问题,因为我没有通过搜索互联网找到答案。我正在创建一个向导窗口。我有一个窗口,顶部有一个标题,底部的按钮会在整个页面中保留。因此,在窗口的xaml.cs中,我有一个UserControls列表,其中包含向导的所有视图。我还有一个包含当前视图的属性/字段。我想创建一个绑定到当前视图属性的 xaml UserControl 标记。当我更改当前视图属性时它应该更改(我已经实现了INotifyChanged接口)。当前视图属性将由c#更改。这是我的代码(简化以显示所需的代码),当我运行它时,在视图区域中没有任何显示:

WizardWindow.xaml:

<Window x:Class="WizardWindow.WizardWindow"...>
    <Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="70"/>
        <RowDefinition Height="*"/>
        <RowDefinition Height="50"/>
    </Grid.RowDefinitions>
    <Grid Grid.Row="0">
        <TextBlock Text="Wizard Title"/>
    </Grid>
    <Grid Grid.Row="1">
        <Border Name="WizardWindowPageContent" Margin="5" BorderBrush="Black" BorderThickness="1">


            <!--This is what I have tried but isn't working -->
            <UserControl Content="{Binding CurrentView}" />


        </Border>
    </Grid>
    <Grid Grid.Row="2" Name="WizardButtons">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        <Button Grid.Column="0">Cancel</Button>
        <Button Grid.Column="2">Back</Button>
        <Button Grid.Column="3">Next</Button>
    </Grid>
</Grid>
</Window>

WizardWindow.xaml.cs:

using System;
...
using System.Windows.Controls;

namespace WizardWindow
{
    public partial class WizardWindow : Window, INotifyPropertyChanged
    {
        // List of views in the config window
        private List<UserControl> views;

        // Current view showing in the window
        private UserControl currentView;
        public UserControl CurrentView
        {
            get { return currentView; }
            set
            {
                currentView = value;
                OnPropertyChanged("CurrentView");
            }
        }

        // Used to keep track of the view index 
        private int viewIndex;

        public WizardWindow ()
        {
            InitializeComponent();
            // Set the screen to the center of the screen
            WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;

            views = new List<UserControl>();

            views.Add(new FirstWizardPage(this));

            viewIndex = 0;
            CurrentView = views[viewIndex];
        }

        public event PropertyChangedEventHandler PropertyChanged;

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

FirstWizardPage.xaml:

<!-- This should show up in the window -->
<UserControl x:Class="WizardWindow.FirstWizardPage" ... >
    <Grid>
            <TextBlock>Lorem Ipsum ...</TextBlock>
    </Grid>
</UserControl>

FirstWizard.xaml.cs:

using System.Windows.Controls;

namespace WizardWindow
{
    public partial class FirstWizardPage : UserControl
    {
        public FirstWizardPage(WizardWindow window)
        {
            InitializeComponent();
        }
    }
}

如果我想重写我的程序,给定的可能重复Window vs Page vs UserControl for WPF navigation? 是一个很好的解决方案。但是,它不能解决我的确切问题。其他人可能有类似的问题,需要这个解决方案。

2 个答案:

答案 0 :(得分:1)

you need to use this:

<ContentControl x:Name="MyView"
                Content="{Binding CurrentView}" />

It should work for you, but it's not MVVM.

答案 1 :(得分:1)

如果要使用MVVM,则必须绑定用户控件的属性DataContext。 我会为你展示一些例子:

是MainWindow.xaml:

<Window x:Class="WpfApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:WpfApp2"
    xmlns:cefSharp="clr-namespace:CefSharp.Wpf;assembly=CefSharp.Wpf"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <local:Foo DataContext="{Binding UserControlViewModel}"/>
</Grid>

是MainWindow.xaml.cs:

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        DataContext = new MainWindowViewModel();
    }

}

是MainWindowViewModel.cs:

 public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        UserControlViewModel = new UserControlViewModel{ Name = "Hello World" };
    }
    public UserControlViewModel UserControlViewModel { get; }
}

是Foo.xaml:

<UserControl x:Class="WpfApp2.Foo"
         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:local="clr-namespace:WpfApp2"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid>
       <TextBlock Text="{Binding Name}"/> 
</Grid>

是FooUsercontrolViewModel.cs

public class FooUserControlViewModel
{
    public string Name { get; set; }
}