none
Выборка в одном UserControl вывод данных в другом UserControl RRS feed

  • Вопрос

  • Мне нужно сделать выборку данных в одном UserControl, а отобразить данные в другом UserControl как сделать?

    первый UserControlCTRL в TestWPF.Control; второй UserControlDT в TestWPF.Data;

    база в папке Baza

    В первом UserControlCtrl я в TextBox например ставлю 1 и по нажатию кнопки Button делаю выборку из базы первой строки и записываю из поля [namebaze] во второй UserControlDT в Label 

    23 апреля 2012 г. 8:06

Ответы

  • Добрый день, коллега.

    Для начала, я бы вам посоветовал почитать про MVVM, Entity Framework. Т.к. то что вы показываете не очень концептуально правильно. Но если решать вашу задачу, то:

    1. Добавить в UserControlCtrl.xaml.cs вот такое событие, и соответственно обработчик Button_Click

    public event RoutedPropertyChangedEventHandler<string> TextChanged;
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                if (TextChanged != null)
                {
                    TextChanged(this, new RoutedPropertyChangedEventArgs<string>("", textbox1.Text);
                }
            }

    2. Во второй контрол добавить свойство, которое будет устанавливать текст в Label:

            public string LabelText
            {
                set
                {
                    label1.Content = value;
                }
            }

    3. В конструктор главной формы добавить подписку на указанное событие и метод, который будет загружать данные и передавать их во второй контрол:

    usr1.TextChanged += usr1_TextChanged;
    
    void usr1_TextChanged(object sender, RoutedPropertyChangedEventArgs<string> e)
    {
        string text = e.NewValue;
        string namebaze = "";
        // Здесь вставить загрузку из БД нужной строки (ADO, Entity Framework)
        usr2.LabelText = namebaze;
    }
    Если проблема с загрузкой, давайте тоже напишу.



    23 апреля 2012 г. 8:41
    Отвечающий
  • Не Grid1 и Grid2, а просто Grid.

    Основная идея в том, что XAML это не более чем альтернативный способ вызова конструктора классов. Ну и размещение одних контролов в других. Например ваша строка:

    <user:UserControl1 x:Name="u1" />
    

    Не более чем вызов конструктора:

    new UserControl1() { Name = "usr1" }

    Или, отвечая на ваш вопрос: да, то что создано из XAML можно удалять из кода.

    Например, у вас в XAML есть вот такая разметка:

    <Grid x:Name="grMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="Первый" />
        <TextBlock Grid.Column="1" Text="Второй" />
        <Button Grid.Column="2" Content="Удалить" Click="Button_Click_1" /> 
    </Grid>

    И вот такой обработчик:

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        grMain.Children.RemoveAt(0);
    }
    При кликах на кнопку у вас с грида будут удаляться компоненты. Сначала первый TextBlock, потом второй, ну и в конце сама кнопка ;)
    • Помечено в качестве ответа developers_s 24 апреля 2012 г. 11:12
    24 апреля 2012 г. 9:39
    Отвечающий

Все ответы

  • Главное окно

    <Window
            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" mc:Ignorable="d" x:Class="TestWPF.MainWindow"
            Title="MainWindow" Height="768" Width="1024" Loaded="Window_Loaded_1">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="511*"/>
                <ColumnDefinition Width="506*"/>
            </Grid.ColumnDefinitions>
            <Grid Name="Grd1"/>
            <Grid Grid.Column="1" Name="Grd2"/>
    
        </Grid>
    </Window>
    

    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;
    using TestWPF.Control;
    using TestWPF.Data;
    
    namespace TestWPF
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public MainWindow()
            {
                InitializeComponent();
            }
    
            private void Window_Loaded_1(object sender, RoutedEventArgs e)
            {
                UserControlCtrl usr1 = new UserControlCtrl();
                UserControlDT usr2 = new UserControlDT();
                Grd1.Children.Add(usr1);
                Grd2.Children.Add(usr2);
            }
        }
    }
    

    23 апреля 2012 г. 8:08
  • Первый UserControl

    using TestWPF.Control;
    
    <UserControl x:Class="TestWPF.Control.UserControlCtrl"
                 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>
            <Button Content="Button" HorizontalAlignment="Left" Margin="10,23,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click_1"/>
            <TextBox HorizontalAlignment="Left" Margin="104,23,0,0" TextWrapping="Wrap" VerticalAlignment="Top" Width="70"/>
    
        </Grid>
    </UserControl>

    второй UserControl 

    using TestWPF.Data;
    <UserControl x:Class="TestWPF.Data.UserControlDT"
                 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>
            <Label Content="Label" HorizontalAlignment="Left" Margin="115,86,0,0" VerticalAlignment="Top"/>
    
        </Grid>
    </UserControl>


    • Изменено developers_s 23 апреля 2012 г. 8:09
    23 апреля 2012 г. 8:09
  • CREATE TABLE [dbo].[Table] (
        [IdDTbaza] SMALLINT      IDENTITY (1, 1) NOT NULL,
        [namebaze] NVARCHAR (50) NULL,
        PRIMARY KEY CLUSTERED ([IdDTbaza] ASC)
    );
    
    SET IDENTITY_INSERT [dbo].[Table] ON
    INSERT INTO [dbo].[Table] ([IdDTbaza], [namebaze]) VALUES (1, N'Первый')
    INSERT INTO [dbo].[Table] ([IdDTbaza], [namebaze]) VALUES (2, N'Второй')
    INSERT INTO [dbo].[Table] ([IdDTbaza], [namebaze]) VALUES (3, N'Третий')
    INSERT INTO [dbo].[Table] ([IdDTbaza], [namebaze]) VALUES (4, N'Четвертый')
    INSERT INTO [dbo].[Table] ([IdDTbaza], [namebaze]) VALUES (5, N'Пятый')
    SET IDENTITY_INSERT [dbo].[Table] OFF
    
    Это скрипты базы

    23 апреля 2012 г. 8:10
  • Добрый день, коллега.

    Для начала, я бы вам посоветовал почитать про MVVM, Entity Framework. Т.к. то что вы показываете не очень концептуально правильно. Но если решать вашу задачу, то:

    1. Добавить в UserControlCtrl.xaml.cs вот такое событие, и соответственно обработчик Button_Click

    public event RoutedPropertyChangedEventHandler<string> TextChanged;
    
            private void Button_Click_1(object sender, RoutedEventArgs e)
            {
                if (TextChanged != null)
                {
                    TextChanged(this, new RoutedPropertyChangedEventArgs<string>("", textbox1.Text);
                }
            }

    2. Во второй контрол добавить свойство, которое будет устанавливать текст в Label:

            public string LabelText
            {
                set
                {
                    label1.Content = value;
                }
            }

    3. В конструктор главной формы добавить подписку на указанное событие и метод, который будет загружать данные и передавать их во второй контрол:

    usr1.TextChanged += usr1_TextChanged;
    
    void usr1_TextChanged(object sender, RoutedPropertyChangedEventArgs<string> e)
    {
        string text = e.NewValue;
        string namebaze = "";
        // Здесь вставить загрузку из БД нужной строки (ADO, Entity Framework)
        usr2.LabelText = namebaze;
    }
    Если проблема с загрузкой, давайте тоже напишу.



    23 апреля 2012 г. 8:41
    Отвечающий
  • Я изучаю литературу, но в силу времени и занятости получается по "малу" информации (к сожалению). Конечно прога наверное выстроена неправильно. Буду исправлять и улучшать. Спасибо.
    23 апреля 2012 г. 9:37
  • namespace TestWPF
    {
        /// <summary>
        /// Interaction logic for MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            DtbaseEntities dtb = new DtbaseEntities();
            public MainWindow()
            {
                InitializeComponent();
                //UserControlCtrl.TextChanged += usr1_TextChanged;
                usr1.TextChanged += usr1_TextChanged;
            }
    
            private void Window_Loaded_1(object sender, RoutedEventArgs e)
            {
                UserControlCtrl usr1 = new UserControlCtrl();
                UserControlDT usr2 = new UserControlDT();
                Grd1.Children.Add(usr1);
                Grd2.Children.Add(usr2);
            }
    
            void usr1_TextChanged(object sender, RoutedPropertyChangedEventArgs<string> e)
            {
                string text = e.NewValue;
                string namebaze = "";
                // Здесь вставить загрузку из БД нужной строки (ADO, Entity Framework)
                // var te = dtb.Table.Where(c => c.IdDTbaza == 1).FirstOrDefault();
                usr2.LabelText = namebaze;
            }
        }
    }



    Чего то не пойму пишет нет в текущем контексте usr1 и usr2

    тут же как бы зона видимости если не внутри фигурных скобок то вроде как не видит, может паблик сделать. Сейчас попробую.

    сделал public void Window_Loaded_1 не помогло.

    Выборку из базы только начал, но даже проверить выборку не смог т.к. пишет ошибку про отсутствие в текущем контексте.





    • Изменено developers_s 23 апреля 2012 г. 17:50
    23 апреля 2012 г. 17:46

  • Сделал так

            public void Window_Loaded_1(object sender, RoutedEventArgs e)
            {
                UserControlCtrl usr1 = new UserControlCtrl();
                UserControlDT usr2 = new UserControlDT();
                Grd1.Children.Add(usr1);
                Grd2.Children.Add(usr2);
                usr1.TextChanged += usr1_TextChanged;
            }

     usr1 из ошибки пропал. Но как я понимаю 

    Window_Loaded_1

    это не конструктор

    • Изменено developers_s 23 апреля 2012 г. 17:53
    23 апреля 2012 г. 17:52
  • Да Window_Loaded - это не контруктор класса главного окна, а событие вызывающееся по окончанию загрузки его. Вы UserControl объекты создаете кодом и добавляете в разметку тоже динамически? Вполне нормально если вы создаете там элемент и добавляете его к текущей разметке.


    Для связи [mail]

    24 апреля 2012 г. 6:13
  • А вообще вам объявление UserControlCtrl usr1 нужно вынести из контруктора/события на уровень класса или сразу описать его в xaml. Тогда подписка на событие в конструкторе будет работать без ошибок.

    Для связи [mail]

    24 апреля 2012 г. 6:15
  • А вообще вам объявление UserControlCtrl usr1 нужно вынести из контруктора/события на уровень класса или сразу описать его в xaml. 


    Вынести в класс - попробую, а в xaml новых ошибок не будет (у меня в Grid.Children грузятся разные UserControl)

    в xaml  я так понимаю надо будет так

    <Grid1> <user:UserControl1 x:Name="u1" /> </Grid>

    <Grid2>
            <user:UserControl2 x:Name="u2" />
    </Grid>

    Но уже UserControl3 то будет у меня опять же динамически подгружаться, смогу я из Grid.Children убрать инициализированный в xaml UserControl. Или там придётся убирать функцию только для чтения и т.п. ?

    Спасибо


    • Изменено developers_s 24 апреля 2012 г. 9:18
    24 апреля 2012 г. 9:17
  • Не Grid1 и Grid2, а просто Grid.

    Основная идея в том, что XAML это не более чем альтернативный способ вызова конструктора классов. Ну и размещение одних контролов в других. Например ваша строка:

    <user:UserControl1 x:Name="u1" />
    

    Не более чем вызов конструктора:

    new UserControl1() { Name = "usr1" }

    Или, отвечая на ваш вопрос: да, то что создано из XAML можно удалять из кода.

    Например, у вас в XAML есть вот такая разметка:

    <Grid x:Name="grMain">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
            <ColumnDefinition Width="1*" />
        </Grid.ColumnDefinitions>
        <TextBlock Grid.Column="0" Text="Первый" />
        <TextBlock Grid.Column="1" Text="Второй" />
        <Button Grid.Column="2" Content="Удалить" Click="Button_Click_1" /> 
    </Grid>

    И вот такой обработчик:

    private void Button_Click_1(object sender, RoutedEventArgs e)
    {
        grMain.Children.RemoveAt(0);
    }
    При кликах на кнопку у вас с грида будут удаляться компоненты. Сначала первый TextBlock, потом второй, ну и в конце сама кнопка ;)
    • Помечено в качестве ответа developers_s 24 апреля 2012 г. 11:12
    24 апреля 2012 г. 9:39
    Отвечающий
  • У меня есть Grid разбитый по столбцам. В одном столбце grdi1 в другом grid2. А в них я уже гружу UserControl - ы. Может неправильно но так удобней :). В Xaml сразу задал Margin="0" и всё. Загрузка UserCotrol сразу на весь столбец никакого кода C# нет. А так наверное придётся прописывать загрузить в Grid c такими то такими то параметрами. :) Спасибо

    24 апреля 2012 г. 11:11