2013-06-03 5 views
2

Как я могу получить доступ к данным/свойствам из UserControl и родителя, MainWindow (и наоборот)? Например, скажем, у меня есть TextBox в моем MainWindow под названием mainTextBox. Затем я создаю UserControl с другим TextBox под названием ucTextBox. У меня также есть кнопка, которая называется ucButton в UserControl, которая должна всплывать MessageBox с продуктом значений mainTextBox.Text * ucTextBox.Text (конвертировано в двойное, чтобы оно работало).Отношения между UserControl и MainWindow

Что я действительно хочу знать, так это то, как добиться этого динамически, с помощью кнопки, которая позволяет создавать больше UserControls, которые способны взаимодействовать с родителем. В этом случае нет смысла называть каждый UserControl.

Я пробовал несколько вещей, в основном с get, заданными свойствами, но без желаемого результата. Я не уверен, что мне нужно использовать UserControl, но, похоже, я читал, что CustomControl предназначен для глубокой настройки, но мне это не нужно.

+2

Просто используйте модель. Ваша основная форма будет читать/записывать в (двойное) свойство в модели, и каждый пользовательский элемент управления получит доступ к этому свойству для чтения. Взгляните на [этот пример] (http://www.codeproject.com/Articles/28060/WPF-UserControl-DataTemplate) (ну и в вашем случае вам может даже не понадобиться шаблон данных). –

ответ

2

Вот лишь краткий пример, чтобы вы начали (и что, вероятно, имеется в виду под г-н @Adriano.):

RootViewModel.cs:

public class RootViewModel :INotifyPropertyChanged 
{ 
    #region Implementation of INotifyPropertyChanged 

    public event PropertyChangedEventHandler PropertyChanged = delegate {}; 

    private void OnPropertyChanged(string propertyName) 
    { 
     PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 

    #endregion 

    private double _x; 
    private double _y; 

    public double X 
    { 
     get { return _x; } 
     set 
     { 
      _x = value; 
      OnPropertyChanged("X"); 
     } 
    } 

    public double Y 
    { 
     get { return _y; } 
     set 
     { 
      _y = value; 
      OnPropertyChanged("Y"); 
     } 
    } 

    public double XY 
    { 
     get { return _x * _y; } 
    } 
} 

UserControl1.xaml:

<UserControl x:Class="WpfApplication2.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:DesignWidth="200"> 
<Grid> 
    <GroupBox Header="User Control"> 
     <StackPanel> 
      <Label Content="Y:" /> 
      <TextBox Text="{Binding Path=Y, UpdateSourceTrigger=PropertyChanged, FallbackValue=1}" Margin="5" /> 
      <Button Content="Press me" Click="OnButtonClick" /> 
     </StackPanel> 
    </GroupBox> 
</Grid> 

UserControl1.xaml.cs:

public partial class UserControl1 : UserControl 
{ 
    public UserControl1() 
    { 
     InitializeComponent(); 
    } 

    private void OnButtonClick(object sender, RoutedEventArgs e) 
    { 
     var viewModel = (RootViewModel)DataContext; 
     var resultMessage = string.Format("{0} * {1} = {2}", viewModel.X, viewModel.Y, viewModel.XY); 

     MessageBox.Show(resultMessage, "X * Y"); 
    } 
} 

MainWindow.xaml:

<Window x:Class="WpfApplication2.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:WpfApplication21="clr-namespace:WpfApplication2" 
    Title="Main Window" Height="350" Width="525"> 
<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition /> 
    </Grid.RowDefinitions> 
    <StackPanel> 
     <Label Content="X:" /> 
     <TextBox Text="{Binding Path=X, UpdateSourceTrigger=PropertyChanged, FallbackValue=1}" Margin="5" Height="24" /> 
    </StackPanel> 
    <WpfApplication21:UserControl1 Grid.Row="1" Margin="5" /> 
</Grid> 

MainWindow.xaml.cs:

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

     DataContext = new RootViewModel 
     { 
      X = 5, 
      Y = 7 
     }; 
    } 
} 
+0

Это замечательно! Но поскольку я очень новичок в этом мире ViewModels, что действительно делает DataContext = новый RootViewModel? BTW, этот пример можно адаптировать для вставки большего количества UserControls и работать независимо? Если я вставляю другой, поскольку он привязан к Y, все UserControls показывают одинаковое значение. Спасибо. – Sturm

+0

Вкратце - все видимые элементы в WPF имеют специальное свойство - ** DataContext **, которое может содержать любой объект и из которого вы могли бы получить (или установить!) Данные для/из вашего этого или других элементов пользовательского интерфейса со специальным синтаксисом в xaml называется ** Связывание данных **. В течение долгого (но * чрезвычайно важного!) Ответа вы должны больше узнать о концепции привязки данных в WPF. Хорошее место для запуска может быть здесь - http://msdn.microsoft.com/en-us/library/ms752347.aspx – Sevenate

+0

Что касается адаптируемости для большего количества UserControls - конечно, да, но как это сделать, зависит от того, что именно вы пытаетесь достичь. – Sevenate

Смежные вопросы