DataBinding к Listview

У меня есть listview, который я связал (двухсторонний) с таблицей данных. Привязка хорошо работает, и данные подходят правильно на listview. Теперь то, чего я хочу достигнуть, немного сложно, и я даже не уверен, может ли это быть достигнуто или теперь.

Моя таблица данных имеет, говорят, что 15 столбцов, и я показываю 5 столбцов в lisview. Действительно ли возможно, что, если пользователь выбирает строку на listview, я мог бы отобразить другие 10 значений для той выбранной строки (из таблицы данных) в textblocks в stackpanel. Это достижимо, или я слишком требователен? Я пытался достигнуть этого путем получения идей от вопроса здесь, но не мог достигнуть этого. Если это достижимо, можете Вы парни давать мне идеи о том, как возобновить это?

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

Я присоединяю свой код ниже. Это - просто тестовый проект с одним listview наличие одного столбца.

XAML:


    


    
        
            
                
            
            
                
                    
                        
                            
                                
                                    
                                    

                                    
                                        
                                
                            
                        
                    
                
            
        
        
            
        
    

Window1.xaml.cs

public partial class Window1 : Window
{
    DataTable dt = new DataTable();
    public Window1()
    {
        InitializeComponent();
        Tables.Instance.dtAccounts = Worker.LoadAccounts();
    }

}

Класс Tables.cs

public class Tables : INotifyPropertyChanged
{
    private static Tables instance;
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private DataTable _dtAccounts;

    public Tables()
    {
    }

    // Singleton instance read-only property
    public static Tables Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Tables();
            }
            return instance;
        }
    }

    public DataTable dtAccounts
    {
        get
        {
            return _dtAccounts;
        }
        set
        {
            _dtAccounts = value;
            OnPropertyChanged("dtAccounts");
        }
    }

    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    } 
}

=====================

Заключительный рабочий код

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

XAML:


    
        
            
                
            
            
                
                    
                        
                            
                                
                                    
                                    

                                    
                                        
                                
                            
                        
                    
                
            
        
        
            
                
                    

                    
                
            
        
    

Window1.xaml.cs

public partial class Window1 : Window
{
    DataTable dt = new DataTable();
    public Window1()
    {
        InitializeComponent();
        Tables.Instance.dtAccounts = Worker.LoadAccounts();
    }

    private void listView1_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        ListView lstView = sender as ListView;
        int item = lstView.SelectedIndex;
        Tables.Instance.SetSelectedRow(item);
    }
}

Tables.cs

public class Tables : INotifyPropertyChanged
{
    private static Tables instance;
    public event PropertyChangedEventHandler PropertyChanged = delegate { };
    private DataTable _dtAccounts;
    private string _selectedName;

    public Tables()
    {
    }

    // Singleton instance read-only property
    public static Tables Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Tables();
            }
            return instance;
        }
    }

    public DataTable dtAccounts
    {
        get
        {
            return _dtAccounts;
        }
        set
        {
            _dtAccounts = value;
            OnPropertyChanged("dtAccounts");
        }
    }

    public string SelectedName
    {
        get
        {
            return _selectedName;
        }
        set
        {
            _selectedName = value;
            OnPropertyChanged("SelectedName");
        }

    }

    public void SetSelectedRow(int index)
    {
        int indexNo = index;
        SelectedName = dtAccounts.Rows[index][0].ToString();
    }

    private void OnPropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    } 
}

1
задан Community 23 May 2017 в 12:13
поделиться

2 ответа

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

  1. Создайте полевую переменную в классе Tables, которая будет представлять одну строку в вашей таблице данных.
  2. Создайте метод в классе Tables, который устанавливает переменную поля в нужную строку таблицы.
  3. Создайте свойства, раскрывающие значения строки.
  4. Метод Шага #2 должен будет выполнять уведомление об изменениях для всех свойств, открытых в Шаге #3 (OnPropertyChanged).
  5. Обработайте событие selection_changed в вашем коде позади, и из обработчика этого события вызовите метод в вашем классе Tables, который устанавливает выбранную строку.
  6. Привяжите ваши текстовые блоки к свойствам, открытым в Шаге #3.
1
ответ дан 2 September 2019 в 23:32
поделиться

Вот что-то вроде этого:

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

        ObservableCollection<Person> personList = new ObservableCollection<Person>();

        personList.Add(new Person() { FirstName = "John", LastName = "Doe", Age = 30, Address = "123 Doe Street", Phone = "111-111-1111" });
        personList.Add(new Person() { FirstName = "Jane", LastName = "Doe", Age = 28, Address = "123 Doe Street", Phone = "222-222-2222" });
        personList.Add(new Person() { FirstName = "Mark", LastName = "Doe", Age = 15, Address = "123 Doe Street", Phone = "333-333-3333" });
        personList.Add(new Person() { FirstName = "John", LastName = "Smith", Age = 40, Address = "123 Doe Street", Phone = "444-444-4444" });
        personList.Add(new Person() { FirstName = "Rosy", LastName = "Smith", Age = 36, Address = "123 Doe Street", Phone = "555-555-5555" });

        PersonListView.ItemsSource = personList;
    }

    private void PersonListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        if (PersonListView.SelectedIndex >= 0)
        {
            Object data = PersonListView.SelectedItem;
            PropertyInfo[] properties = data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance);

            ExtraPropertiesPanel.Children.Clear();

            foreach (PropertyInfo prop in properties)
            {
                TextBox tb = new TextBox();
                Binding b = new Binding() { Source = data, Path = new PropertyPath(prop.Name) };
                tb.SetBinding(TextBox.TextProperty, b);
                ExtraPropertiesPanel.Children.Add(tb);
            }
        }
    }
}

public class Person
{
    public String FirstName { get; set; }
    public String LastName { get; set; }
    public Int32 Age { get; set; }
    public String Address { get; set; }
    public String Phone { get; set; }
}

XAML

<Window x:Class="WPFApplication1.DynamicListViewWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window"
    Height="300"
    Width="300">
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Border Grid.Column="0">
        <ListView Name="PersonListView" SelectionChanged="PersonListView_SelectionChanged">
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="First Name"
                                    DisplayMemberBinding="{Binding FirstName}" />
                    <GridViewColumn Header="Last Name"
                                    DisplayMemberBinding="{Binding LastName}" />
                </GridView>
            </ListView.View>
        </ListView>
    </Border>
    <Border Grid.Column="1">
        <StackPanel Name="ExtraPropertiesPanel"></StackPanel>
    </Border>
</Grid>

1
ответ дан 2 September 2019 в 23:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: