2

Возможно ли привязка Dictionary с внутренним списком ObservableCollection к элементу listbox ? или это можно сделать проще. В данном примере привязки не корректны.


Пояснение: 1)Listbox x:Name="List_dir": отвечает за показ ключей словаря; 2)ListView x:Name="List_dir2" Отвечает за вывод списка(ObservableCollection) по ключу.

Предполагаемый функционал: Создание ключей; Добавление данных в существующий список по ключу; Удаление данных из списка по ключу\Изменение данных из списка по ключу; Поиск ключей в Listbox x:Name="List_dir"

   public class mySelectedItem
    {
        public string Name { get; set; }
        public string Password { get; set; }
        public string Description { get; set; }
    public mySelectedItem(string name, string password,string description)
    {
        Name = name;
        Password = password;
        Description = description;
    }

}

Dictionary<string, ObservableCollection<mySelectedItem>> dict1 = new Dictionary<string, ObservableCollection<mySelectedItem>>();

public MainWindow()
{
    InitializeComponent();
    this.DataContext = this;
    dict1.Add("f1", new ObservableCollection<mySelectedItem>());
    dict1["f1"].Add(new mySelectedItem("log1","pas1","desc1"));
    dict1["f1"].Add(new mySelectedItem("log2","pas2","desc2"));
}

XAML:

        <ListBox x:Name="List_dir" HorizontalAlignment="Stretch" Grid.Row="0"  VerticalAlignment="Stretch" Background="White" Margin="-1,-1,0,-1" ItemsSource="{Binding dict1}" BorderBrush="White" >
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <Image Source="icon/f1.png" MaxWidth="20" MaxHeight="20" Margin="0,0,5,0"/>
                        <TextBlock Text="{Binding Key}" FontFamily="Segoe UI Black" FontSize="14"/>
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>

<ListView x:Name="List2_dir" ItemsSource="{Binding Asset.dict1.Values}" HorizontalAlignment="Stretch" SelectionChanged="ListView_SelectionChanged" Background="{x:Null}" BorderBrush="{x:Null}" Foreground="Red"> <ListView.Resources> <ContextMenu x:Key="ItemContextMenu"> <MenuItem x:Name="menuItem_CopyUsername" Click="menuItem_CopyUsername_Click" Header="Copy Username"> <MenuItem.Icon> <Image Source="icon/def.png" /> </MenuItem.Icon> </MenuItem> <MenuItem x:Name="menuItem_CopyPassword" Click="menuItem_CopyPassword_Click" Header="Copy Password"> <MenuItem.Icon> <Image Source="icon/def.png" /> </MenuItem.Icon> </MenuItem> <Separator /> <MenuItem x:Name="menuItem_DeleteCreds" Click="menuItem_DeleteCreds_Click" Header="Delete"> <MenuItem.Icon> <Image Source="icon/def.png" /> </MenuItem.Icon> </MenuItem> </ContextMenu> </ListView.Resources> <ListView.ItemContainerStyle> <Style TargetType="{x:Type ListViewItem}"> <Setter Property="ContextMenu" Value="{StaticResource ItemContextMenu}" /> </Style> </ListView.ItemContainerStyle> <ListView.View> <GridView AllowsColumnReorder="true"> <GridViewColumn DisplayMemberBinding="{Binding Path=Name}" Header="Логин" Width="150"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Password}" Header="Пароль" Width="150"/> <GridViewColumn DisplayMemberBinding="{Binding Path=Description}" Header="Описание" Width="200"/> </GridView> </ListView.View> </ListView>

Скриншот программы что должно получиться: введите сюда описание изображения

Tand
  • 163
  • Вы не объяснили, что именно вам нужно, но словарь вам точно здесь не нужен. Суть: При выборе itema - это не суть, это хотелка. Суть - это то, зачем все это нужно. И именно ее в вашем вопросе не хватает, чтобы понять, как это можно реализовать. Что содержит ключ словаря? Вангую, что тоже самое, что и свойство Name? Если так, то у вас ошибка проектирования - данные не должны дублироваться. Если нет, то расскажите, что к чему: что делает или должен делать ваш код/приложение? – aepot Feb 14 '21 at 23:50
  • 1
    @aepot Добавил скриншот, может так станет немного понятнее – Tand Feb 15 '21 at 00:03
  • 1
  • @aepot не совсем то что там реализовано. Тут вложенный список в который можно по ключу добавлять элементы, а там этого нету – Tand Feb 15 '21 at 01:11
  • А зачем вам здесь ключ? Вы знаете, чем ObservableCollection от List отличается? – aepot Feb 15 '21 at 06:31
  • @aepot а каким образом можно обойтись без ключа, когда нам нужно добавить не 1 строчку с данными. Вот вы прислали пример https://ru.stackoverflow.com/questions/1140779/%d0%9a%d0%b0%d0%ba-%d0%be%d1%82%d0%be%d0%b1%d1%80%d0%b0%d0%b6%d0%b0%d1%82%d1%8c-%d0%ba%d0%be%d0%bd%d0%ba%d1%80%d0%b5%d1%82%d0%bd%d1%83%d1%8e-%d1%81%d1%82%d1%80%d0%be%d0%ba%d1%83-datagrid-%d0%b2-%d0%b7%d0%b0%d0%b2%d0%b8%d1%81%d0%b8%d0%bc%d0%be%d1%81%d1%82%d0%b8-%d0%be%d1%82-%d0%b2%d1%8b%d0%b1%d1%80%d0%b0%d0%bd%d0%bd%d0%be%d0%b3%d0%be-%d1%8d%d0%bb%d0%b5%d0%bc%d0%b5%d0%bd%d1%82%d0%b0-l – Tand Feb 15 '21 at 16:44
  • Там реализовано просто, я так сделал. Но нет идей как можно добавить не 1 строчку с логином\паролем\описанием – Tand Feb 15 '21 at 16:44
  • @EvgeniyZ То есть заместо словаря можно так? public ObservableCollection<KeyValueCollection> Models { get; set; } = new ObservableCollection<KeyValueCollection>(); – Tand Feb 16 '21 at 11:06
  • { public string Name { get; set; } public ObservableCollection<Model> Data_list { get; set; } public KeyValueCollection() { Data_list = new ObservableCollection<Model>(); } }``` – Tand Feb 16 '21 at 11:06
  • и далее мы можем добавлять\создавать и т.д. Но как привязать все это дело в wpf.Models.Add(new KeyValueCollection { Name = "asdfg" }); var item = Models.FirstOrDefault(i => i.Name == "asdfg"); if (item != null) { item.Data_list.Add(new Model { Name = "Folder", Login = "Folder", Password = "Folder", Description = "Folder" }); } – Tand Feb 16 '21 at 11:18
  • 1
    Я же вам дал ссылку на дубликат, где подробно описывается то, что вы хотите. По сути, без разницы что за тип будете вы использовать, за исключением только того, что ObservableCollection реализует INotifyCollectionChanged, что позволяет автоматически, без вашего участия, обновить интерфейс при добавлении/удалении объекта. – EvgeniyZ Feb 16 '21 at 11:51
  • 1
    Но как привязать все это дело - опять же, ссылка выше, где вы можете увидеть, что у ListBox надо задать IsSynchronizedWithCurrentItem="True", это позволит синхронизировать другие элементы с тем, что выбрано в нем, ну и соотстветственно его надо привязать (ItemsSource = "{Binding dict1}" (или в случае вашего комментария ItemsSource = "{Binding Models}"), далее ему надо переопределить ListBox.ItemTemplate, задав там нужный вид отображения (в случае словаря будет {Binding Key}, а в случае коллекции {Binding Name}). – EvgeniyZ Feb 16 '21 at 12:00
  • 1
    Теперь остается ListView, который мы привязываем таким образом в случае словаря: ItemsSource = "{Binding dict1/Value}", в случае коллекции: ItemsSource = "{Binding dict1/Data_list}". Обратите внимание на /, через нее какраз и задается дальше свойство для синхронизации, то есть левая часть должна быть идентична той, что вы указывали у ListBox, а правая должна указывать на свойство для привязки (в вашем случае коллекция). Все, вот вы и привязали в пару строк кода все данные, вид только не забудьте указать для ListView нужный. Если что не ясно, то читайте дубликат, внимательней! – EvgeniyZ Feb 16 '21 at 12:05

0 Answers0