Привязка к полю со списком WPF в виде списка (двусторонняя)

#c# #wpf #data-binding

#c# #wpf #привязка к данным

Вопрос:

У меня возникла проблема с необходимостью привязки выбранного значения поля со списком, встроенного в представление списка. У меня нет проблем с отображением элементов в поле со списком. Однако я хотел бы, чтобы у меня был способ указывать, что должно отображаться в поле со списком (из числа элементов, которые оно содержит), одним нажатием кнопки. Я думаю, что есть несколько сообщений по этому вопросу, однако я не могу получить именно то, что я хочу. Вот мой код.

XAML:

 <Grid>
    <StackPanel Orientation="Vertical">
    <ListView 
        x:Name="OptionsListView" 
        ItemsSource="{Binding MyObjectCollection}">
        <ListView.Resources>
            <DataTemplate x:Key="comboBoxTemplate">
                <ComboBox 
                        Margin="0,3" 
                        x:Name="MyTypeComboBox" 
                        SelectedValue="{Binding Path=SelectedType, Mode=TwoWay}">
                    <ComboBoxItem Content="ABC"/>
                    <ComboBoxItem Content="DEF"/>
                    <ComboBoxItem Content="XYZ"/>
                </ComboBox>
            </DataTemplate>
        </ListView.Resources>
        <ListView.View>

            <GridView>
                <GridViewColumn Header="Text-Sample" 
                                    Width="100">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>
                <GridViewColumn Header="Combo-Sample" 
                                    Width="100"
                                    CellTemplate="{StaticResource comboBoxTemplate}" />
            </GridView>
        </ListView.View>
    </ListView>
    <Button Click="Button_Click">Click Me!</Button>
    </StackPanel>
</Grid>
  

Код C #, лежащий в основе:

 public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        OptionsListView.DataContext = this;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        //Something here that dictates what should be displayed in the combo box
    }

    List<MyObject> myObjectCollection = new List<MyObject>();
    public List<MyObject> MyObjectCollection
    {
        get
        {
            myObjectCollection.Add(new MyObject("One"));
            myObjectCollection.Add(new MyObject("Two"));
            return myObjectCollection;
        }
    }

}

public class MyObject : INotifyPropertyChanged
{
    private string _name;

    public MyObject(string name)
    {
        // TODO: Complete member initialization
        this._name = name;
    }

    public string Name
    {
        get
        {
            return _name;
        }
    }

    string selectedType = string.Empty;
    public string SelectedType
    {
        get
        {
            return selectedType;
        }
        set
        {
            selectedType = value;
            this.NotifyChange("SelectedType");
        }
    }

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    private void NotifyChange(params object[] properties)
    {
        if (PropertyChanged != null)
        {
            foreach (string p in properties)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(p));
            }
        }
    }
    #endregion
}
  

Я был бы рад, если бы кто-нибудь мог помочь мне взломать это..

Спасибо Ram

Ответ №1:

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

Смотрите код ниже.

XAML:

 <ComboBox Margin="0,3" 
    x:Name="MyTypeComboBox" 
    ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ListBox},Path=DataContext.Sources}"
    SelectedValue="{Binding Path=SelectedType, Mode=TwoWay}">
</ComboBox>
  

Код на C #:

 private Collection<string> sources = new Collection<string>() { "ABC", "DEF", "XYZ" };
public Collection<string> Sources { get { return sources; } }

private void Button_Click(object sender, RoutedEventArgs e)
{
    myObjectCollection[0].SelectedType = Sources[0];
    myObjectCollection[1].SelectedType = Sources[2];
}
  

Комментарии:

1. Большое спасибо, Говард.. Теперь все работает нормально! По-видимому, я пытался установить поле со списком со значением, которое не было привязано к нему. И теперь, когда я указал (как вы и предлагали) коллекцию, которая должна быть привязана к полю со списком, все работает как по маслу! Я прав? Была ли привязка данных к полю со списком с использованием ItemSource ключевым моментом здесь? Большое спасибо!

Ответ №2:

Как насчет

 foreach (ComboBox c in OptionsListView.Items)
            {
                c.SelectedValue = "Put your value here";
            }
  

Это должно сработать, если у вас внутри есть другие объекты, кроме полей со списком, вы можете добавить

 if (c is ComboBox)
  

чтобы убедиться, что вы работаете с правильным объектом

Комментарии:

1. Привет, Дамаск, я не думаю, что твое предложение работает. Мой listview привязан к коллекции MyObject и, следовательно, foreach не видит поле со списком в OptionsListView. Товары. Он видит только элементы типа MyObject, что именно и было моей проблемой. К счастью, предложение Говарда помогло! В любом случае, большое спасибо за быструю мысль по этому вопросу.

2. Мне кажется странным, что это не срабатывает. ListView.Item выдает вам ItemCollection файл, содержащий все визуальные элементы управления, отображаемые в вашем списке (т. Е. Здесь со списком), если вам нужен список с, MyObjects вы должны использовать свойство ItemsSource , например. В любом случае, надеюсь, я мог бы помочь