2014-07-03 75 views
-1

這可能是一個簡單的問題,但我在WPF和C#中很新。如何從用戶控件和動態顯示用戶控件獲取值

我的目標:

  1. 幾個用戶控件
  2. 每個用戶控件有很多chechboxes的,文本框;
  3. 動態顯示用戶控件---一次只顯示一個用戶控件 ;
  4. 從Mainwindow獲取usercontrols的值。

我曾嘗試兩種方法:

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,I可以訪問用戶控件的值,但不能動態顯示用戶控件; 對於方法2,我可以動態顯示usercontrol,但我無法獲得usercontrol的正確值。

我的問題是什麼?我該怎麼辦?

回答

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(); 
     } 
    } 
} 
+0

非常感謝。你的回答正是我想要的。而且我感到你的代碼中的評論對我非常有幫助。再次感謝你。 – user3799965

0

我認爲,如果你開始使用WPF,你應該學會使用The MV-VM Pattern。你想要做什麼可以用它一個很好的方式來解決:

  1. 首先,你應該有一個MainViewModel,爲此,你要顯示的每個不同的視圖中的視圖模型(作爲用戶控件)。
  2. 在主ViewModel中,您可以使用一個屬性來表示所顯示的選定內容(ViewModel)。
  3. 然後你應該爲每個視圖模型創建一個DataTemplate,在每個視圖模型中你可以放置你的用戶控件。
  4. 最後在主窗口中創建用於顯示選定內容的內容控件。

這是關於執行方式的一個想法。希望可以幫助你以正確的方式引導你...