如何从usercontrol&获取值动态显示usercontrol

时间:2014-07-03 11:42:20

标签: wpf

这可能是一个简单的问题,但我在WPF和C#中都很新。

我的目标:

  1. 多个用户控件
  2. 每个usercontrol都有很多cheboxbox,textboxes;
  3. 动态显示usercontrols ---只有一个用户控件 一次显示;
  4. 从Mainwindow获取用户控件的值。
  5. 我尝试了两种方法:

    1---MainWindow.XAML: local:myusercontrol name="myusercontrolinst" ;    
        Mainwindow.XAML.cs: string Result=myusercontrolinst.Value;    
    2---MainWindow.XAML:contentcontrol name="mycontentcontrol";   
        Mainwindow.XAML.cs: mycontentcontrol.content=new myusercontrol();  myusercontrol mycontrol=new myusercontrol();  string Result=mycontrol.Value;
    

    对于方法1,我可以访问usercontrol的值,但不能动态显示usercontrol;   对于方法2,我可以动态显示usercontrol,但是我无法获得正确的usercontrol值。

    我的问题是什么?我该怎么办?

2 个答案:

答案 0 :(得分:0)

很难回答你的问题。我想我有它的主旨。

这是我认为你要问的一种方式。为简单起见,我只有一个用户控件可以切换出来。按UserControl 1/2按钮加载用户控件。按UserControl Value按钮显示值(文本框中的内容)。

MainWindow.xaml:

<Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>

        <StackPanel Orientation="Horizontal" Grid.Row="0">
            <Button Name="btnUserControl1" Content="UserControl 1" VerticalAlignment="Center" Margin="5" Click="btnUserControl1_Click" />
            <Button Name="btnUserControl2" Content="UserControl 2" VerticalAlignment="Center" Margin="5" Click="btnUserControl2_Click" />
            <Button Name="btnUserControlVal" Content="UserControl Value" VerticalAlignment="Center" Margin="5" Click="btnUserControlVal_Click" />
        </StackPanel>
        <Grid Grid.Row="1" Name="grid">
            <!-- This will hold the loaded user control -->
        </Grid>
    </Grid>
</Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        UserControl userControl = null;

        public MainWindow()
        {
            InitializeComponent();
        }

        private void setUserControl(UserControl uc)
        {
            userControl = uc;
            grid.Children.Clear();
            grid.Children.Add(userControl);
        }

        private void btnUserControl1_Click(object sender, RoutedEventArgs e)
        {
            UserControl1 uc = new UserControl1();
            uc.Label = "User Control 1";
            setUserControl(uc);
        }

        private void btnUserControl2_Click(object sender, RoutedEventArgs e)
        {
            // I'm just reusing UserControl1, you would use a different user control here instead.
            UserControl1 uc = new UserControl1();
            uc.Label = "User Control 2";
            setUserControl(uc);
        }

        private void btnUserControlVal_Click(object sender, RoutedEventArgs e)
        {
            if (userControl != null)
            {
                // If you only have a few user controls then you could just check if it is each one, like this:
                if (userControl is UserControl1)
                {
                    UserControl1 uc = userControl as UserControl1;
                    MessageBox.Show(string.Format("Value of user control is '{0}'.", uc.Value));
                }
                //else if (userControl is UserControl2)
                //{
                //    // ...
                //}

                // Or, you could make an interface and have each UserControl implement it
                //if (userControl is IMyInterface)
                //{
                //    IMyInterface uc = userControl as IMyInterface;
                //    string myVal = uc.GetValue();
                //    MessageBox.Show(string.Format("Value of user control is '{0}'.", myVal));
                //}
            }
        }
    }
}

UserControl1.xaml

<UserControl x:Class="WpfApplication3.UserControl1"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>

        <Label Grid.Row="0" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" Content="{Binding Label}" />
        <TextBox Grid.Row="1" DataContext="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}" Text="{Binding Value}" Name="textbox1" Margin="5" />
    </Grid>
</UserControl>

UserControl1.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfApplication3
{
    /// <summary>
    /// Interaction logic for UserControl1.xaml
    /// </summary>
    public partial class UserControl1 : UserControl
    {
        public string Label
        {
            get { return (string)GetValue(LabelProperty); }
            set { SetValue(LabelProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Label.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty LabelProperty =
            DependencyProperty.Register("Label", typeof(string), typeof(UserControl1), new PropertyMetadata("Unspecified"));

        public string Value
        {
            get { return (string)GetValue(ValueProperty); }
            set { SetValue(ValueProperty, value); }
        }
        // Using a DependencyProperty as the backing store for Value.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty ValueProperty =
            DependencyProperty.Register("Value", typeof(string), typeof(UserControl1), new PropertyMetadata(null));

        public UserControl1()
        {
            InitializeComponent();
        }
    }
}

答案 1 :(得分:0)

我认为如果你开始使用WPF,你应该学会使用The MV-VM Pattern。您想要做的事情可以用一种很好的方式解决:

  1. 首先,您应该为要显示的每个不同视图(作为UserControl)提供MainViewModel和ViewModel。
  2. 在主ViewModel中,您可以拥有一个属性来表示您要显示的所选内容(ViewModel)。
  3. 然后,您应为每个视图模型创建一个DataTemplate,每个模型都可以放置用户控件。
  4. 最后在主窗口中创建内容控件以显示所选内容。
  5. 这是关于实施方式的想法。希望有助于指导您正确的方式......