Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.RU > .NET: Общие вопросы > update данных


Автор: Koss 07.04.13, 13:40
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    <Window x:Class="WpfApplication4.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>
            <TreeView Height="311" HorizontalAlignment="Left" Name="treeView1" VerticalAlignment="Top" Width="503" >
                <TreeViewItem Header='1111'
    ItemsSource="{Binding list_n}">
                    <TreeViewItem.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBlock Text="{Binding name}"/>
                            </StackPanel>
                        </DataTemplate>
                    </TreeViewItem.ItemTemplate>
                </TreeViewItem>
            </TreeView>
        </Grid>
    </Window>

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    namespace WpfApplication4
    {
        /// <summary>
        /// Логика взаимодействия для MainWindow.xaml
        /// </summary>
        public partial class MainWindow : Window
        {
            public List<Item_N> list_n;
            public MainWindow()
            {
                InitializeComponent();
                InitializeComponent();
                list_n = new List<Item_N>();
                list_n.Add(new Item_N { id = 1, name = "1" });
                list_n.Add(new Item_N { id = 2, name = "2" });
                list_n.Add(new Item_N { id = 3, name = "3" });
                list_n.Add(new Item_N { id = 4, name = "4" });
                list_n.Add(new Item_N { id = 5, name = "5" });
                list_n.Add(new Item_N { id = 6, name = "6" });
     
                DataContext = new { list_n };
            }
        }
        public class Item_N
        {
            public int id { get; set; }
            public string name { get; set; }
        }
    }

такой значит, код есть.
Как можно при щелчке на элементе трея обновить привязанное поле name , и сделать его 0, и как сделать чтобы если name равно "0" - сделать айтем, например зелёным ?
WpfApplication4.7z (, : 159)

Автор: Koss 18.04.13, 11:11
никто не знает?
можно упростить. Есть трей, с заданным айтем сорсом.
как при щелчке на текущий айтем сделать что-нибудь с привязанным объектом?

Автор: 100500 18.04.13, 12:07
Задать для treeViewItem MouseLeftButtonUp и в нём изменить свойство у текущего выбранного элемента.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     <TreeViewItem Name="MyGroup" Header='1111'
    ItemsSource="{Binding list_n}" MouseLeftButtonUp="MyGroup_MouseLeftButtonUp">



В коде обработчика:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     private void MyGroup_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
     {
     
     Item_N MySelectedItem = null;
      Type CheckType = treeView1.SelectedItem.GetType();
                if (CheckType.Name == "Item_N")
                {
                     MySelectedItem = (Item_N)treeView1.SelectedItem;
                     MySelectedItem.Name="Я элемент";
                }
    }


В самом классе вроде нужно добавить уведомления для изменения свойств для нашего treeView, иначе он не 'поймёт' что мы меняем свойства элемента.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
      
        public class Item_N: INotifyPropertyChanged
        {
            public int id { get; set; }
          
            private string _name;
     
            public string name
            {
                get
                {
                    return this._name;  
                }
                set
                {
                    try
                    {
                        _name = value;
                        if (PropertyChanged != null)
                        {
                            PropertyChanged(this, new PropertyChangedEventArgs("name"));
                        }
                    }
                    catch (Exception Exception)
                    {
                    }
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;  //вот оно
     
        }


Добавлено
А для того чтобы сделать зелёным, можно создать биндинг на свойство background у TextBlock т.е.

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
     <TextBlock Text="{Binding name}" Background="{Binding BackColor}"/>


в классе:



<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    public class Item_N: INotifyPropertyChanged
        {
            public int id { get; set; }
     
               private Brush _backcolor;
               public Brush BackColor
               {
                    get
                    {
                         return _backcolor;
                    }
                    set
                    {
                         _backcolor = value;
                        if (PropertyChanged != null)
                        {
                            PropertyChanged(this, new PropertyChangedEventArgs("BackColor"));
                        }
                    }
               }
     
     
            private string _name;
     
            public string name
            {
                get
                {
                    return this._name;  
                }
                set
                {
                    try
                    {
                        _name = value;
                        if (PropertyChanged != null)
                        {
                            PropertyChanged(this, new PropertyChangedEventArgs("name"));
                        }
                    }
                    catch (Exception Exception)
                    {
                    }
                }
            }
            public event PropertyChangedEventHandler PropertyChanged;  //вот оно
     
        }


задаём:

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    if(MySelectedItem.Name == "0")
    {
       MySelectedItem.BackColor = (Brush)new BrushConverter().ConvertFromString("Green");
    }

Автор: Koss 18.04.13, 12:23
а вот тут:
public List<Item_N> list_n;
он поменяется?

Добавлено
(Item_N)treeView1.SelectedItem; я смотрел. только возвращает, и всё.

Автор: 100500 18.04.13, 12:33
Цитата
(Item_N)treeView1.SelectedItem; я смотрел. только возвращает, и всё.

Возвращает что?

<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    public List<Item_N> list_n;
Это просто объявление списка с данными которые будут добавляться в группу. Тут ничего не должно меняться

Автор: Koss 18.04.13, 12:57
блин.. я неправильно думал..
Мне казалось, что public List<Item_N> list_n; должен будет так же изменяться.
клацну я там, например на трее в менюшке, "добавить объект", в обработчике кликания будет что-то вроде:
list_n.Add(new Item_N { id = 7, name = "7" });
и он появиться и в трейчике.

Автор: 100500 18.04.13, 13:09
Так надо новый добавить а не обновить существующий?

Автор: Craft 18.04.13, 13:39
Koss Еслы вы хотите чтобы данные обновлялись автоматически используйте ObservableCollection а не List. Если вы добавите в List новый айтем то данные вы не увидете обновленные. Нужно писать как вам писал 100500 об INotifyPropertyChanged и сделать проперти для List<Item_N> list_n. Тогда данные будут обновлены. Попробуйте использовать MVVM паттерн. И отделите код от логики. Так будет проще сопровождать проэкт. Модель вам уже написали.
ViewModel написать не сложно. Вот мое виденье как можно переписать логику.
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
    public class NotifyPropertyChangedBase : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
     
            public void RaisePropertyChanged(string propertyName)
            {
                var propertyChanged = PropertyChanged;
                if (propertyChanged != null)
                    propertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
     
    public class Item_N : NotifyPropertyChangedBase
        {
            public int id { get; set; }
     
            private Brush _backcolor;
            public Brush BackColor
            {
                get
                {
                    return _backcolor;
                }
                set
                {
                    _backcolor = value;
                    RaisePropertyChanged("BackColor");
                }
            }
     
     
            private string _name;
     
            public string Name
            {
                get
                {
                    return this._name;
                }
                set
                {
                    try
                    {
                        _name = value;
                        RaisePropertyChanged("Name");
                    }
                    catch (Exception Exception)
                    {
                    }
                }
            }
     
        }
     
        public class Item_NViewModel : NotifyPropertyChangedBase
        {
            private ObservableCollection<Item_N> _itemsNCollection = new ObservableCollection<Item_N>();
            public ObservableCollection<Item_N> ItemsNCollection
            {
                get { return _itemsNCollection; }
                set
                {
                    _itemsNCollection = value;
                    RaisePropertyChanged("ItemsNCollection");
                }
            }
     
            #region Command
            #endregion
        }
И всю логику пишете во ViewModel. Тогда ваш код будет отделен от View.

Автор: Koss 19.04.13, 04:53
Цитата 100500 @
Так надо новый добавить а не обновить существующий?

insert, update и Delete. На этом примере я с ВПФ разбираюсь.

Автор: Koss 23.04.13, 09:21
начал разбираться в этом MVVM
переделал под этот паттерн. Почему не зеленеет?
WpfApplication4.7z (, : 135)

Добавлено
да.. и почему у меня в текстбоксе можно только первый элемент редактировать?

Автор: Koss 23.04.13, 11:15
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
            public string name
            {
                get { return item.name; }
                set
                {
                    item.name = value;
                    if (value == "0")
                        BackColor = Brushes.Green;
                    OnPropertyChanged("name");
                }
            }
            private Brush _backcolor;
            public Brush BackColor
            {
                get
                {
                    return _backcolor;
                }
                set
                {
                    _backcolor = value;
                    OnPropertyChanged("BackColor");
                }
            }

а почему не работает типа такого:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
            public Brush BackColor
            {
                get
                {
                    return (name=="0" ? Brushes.Green : Brushes.White);
                }
     
            }


Добавлено
да и ещё вопрос есть.. каким боком тут INotifyPropertyChanged взаимодействует?
я ни к каким событиям не подписывался.
Почему , когда убрать наследование от INotifyPropertyChanged ничего не апдейтится?

Автор: Craft 23.04.13, 15:23
Цитата Koss @
да и ещё вопрос есть.. каким боком тут INotifyPropertyChanged взаимодействует?
я ни к каким событиям не подписывался.
Почему , когда убрать наследование от INotifyPropertyChanged ничего не апдейтится?

Вот таким
Цитата MSDN

Для появления уведомления об изменении привязки клиента и источника данных связанный тип должен:
Либо реализовать интерфейс INotifyPropertyChanged (предпочтительный вариант).
Либо обеспечить событие изменения для каждого свойства связанного типа.
.
Просто для обновления свойста используеться updatesourcetrigger. А почему именно так это работает прочтите об Binding.UpdateSourceTrigger и INotifyPropertyChanged по ссылкам которые вам приводили.

Автор: Koss 23.04.13, 15:36
а почему у меня в геттер не заходит? в отладчике даже ловушку ставил.

Автор: Craft 23.04.13, 17:55
Цитата Koss @
а почему у меня в геттер не заходит? в отладчике даже ловушку ставил.

Потому что обновленные данные получаются через метаданные GetMetadata. Более подробно про то как это работает можно почитать здесь. Либо источник2 на который все ссылаются.

Автор: Koss 24.04.13, 17:41
в смысле вот таким макаром перереализовавать интерфейс:
<{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}>
        public void NotifyPropertyChanged<T>(Expression<Func<T>> property)
        {
            if (PropertyChanged != null)
            {
                var memberExpression = property.Body as MemberExpression;
     
                PropertyChanged(this, new PropertyChangedEventArgs(memberExpression.Member.Name));
            }
        }

?

чтоб туда делегат можно было сувать?

Автор: Koss 25.04.13, 06:06
спасибо, ребята! Вы все волшебники!

Автор: Koss 25.04.13, 12:55
собственно, выложу ссылки . Тут что-то типа MVVM для дебилов. :)

Шпаргалка по MVVM в WPF - В статье рассказывается о основных приемах, используемых при разработке WPF-приложений с использованием MVVM
Паттерн MVVM. Часть 1. - Короткое объяснение прицепов паттера MVVM в WPF-приложениях
Основы MVVM Pattern’а – часть 1. - В статье продемонстрирован хороший пример WPF-приложения с использованием MVVM. Присутствует ссылка на исходный код примера статьи.

это надо добавить в faq

Добавлено
мне помогло)

Автор: maxim84_ 25.04.13, 14:16
Все забываю вам дать ссылку :(

вот, посмотрите: Руководство разработчика Prism - Хорошо расписано как работать с XAML-base инструментами. Так же расписаны основные приемы, паттерны и архитектурные решения. Прочитать этот материал - лишнем не будет.

Автор: Koss 25.04.13, 18:51
Цитата maxim84_ @

Оформите пост для фака более структурировано и понятно. Сообщение будет удалено через 5 дн.

ну ссылки три. для тех, кому нужно вааще по простецки объяснить. Я не знаю, как этооформить

Автор: maxim84_ 25.04.13, 19:23
Цитата
Я не знаю, как этооформить

примерно, как я постом выше.

Автор: maxim84_ 26.04.13, 15:24
Подредактировал ссылки и добавил в FAQ.
Спасибо, за материал.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)