【问题标题】:In a WPF application using Visual Studio, how can I bind a usercontrol to a usercontrol variable?在使用 Visual Studio 的 WPF 应用程序中,如何将用户控件绑定到用户控件变量?
【发布时间】:2018-07-31 23:21:51
【问题描述】:

我不确定我是否正确地提出了这个问题,因为我没有通过搜索互联网找到答案。我正在创建一个向导窗口。我有一个窗口,顶部有标题,底部有按钮,在整个更改页面期间都将保留在那里。因此,在窗口的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? 是一个很好的解决方案。但是,它不能解决我的确切问题。其他人可能有类似的问题并需要此解决方案。

【问题讨论】:

标签: c# wpf xaml


【解决方案1】:

你需要使用这个:

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

它应该适合你,但它不是 MVVM。

【讨论】:

  • 这行得通,但我需要在构造函数的 WizardWindow.xaml.cs 中有this.DataContext = this;
【解决方案2】:

如果你想使用 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; }
}

【讨论】:

  • 感谢您详细说明如何在此上下文中使用 MVVM。但是,我要深入这个项目来重建一切。
猜你喜欢
  • 2013-08-29
  • 1970-01-01
  • 1970-01-01
  • 2013-06-06
  • 2014-01-14
  • 2023-03-16
  • 1970-01-01
  • 2012-04-15
相关资源
最近更新 更多