Привязка данных WPF к комбинированному окну - PullRequest
1 голос
/ 26 апреля 2011

Я новичок в WPF, C # и привязке данных.Я просто пытаюсь привязать простое поле со списком к ObservedCollection.Вот код:

 public class Directory
{
    private string _ikey;
    public string IKey
    {
        get
        {
            return _ikey;
        }
        set
        {
            _ikey = value;
        }
    }
    private string _ivalue;
    public string IValue
    {
        get
        {
            return _ivalue;
        }
        set
        {
            _ivalue = value;
        }
    }

}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window

{
    public ObservableCollection<Directory> DirectoryList = new ObservableCollection<Directory>();

    public MainWindow()
    {
        InitializeComponent();

        DirectoryList = new ObservableCollection<Directory>();
        Directory _dirtemp = new Directory();
        _dirtemp.IKey = "1";
        _dirtemp.IValue = "Steve";
        DirectoryList.Add(_dirtemp);

        _dirtemp = new Directory();
        _dirtemp.IKey = "2";
        _dirtemp.IValue = "John";
        DirectoryList.Add(_dirtemp);




    }
}

Мой xaml выглядит так:

<Window x:Class="DataBindCombo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DataBindCombo"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
              ItemsSource="{Binding Path=DirectoryList}"
              DisplayMemberPath="IValue"
              SelectedValuePath="IKey"
              >

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

Есть идеи?ТИА

Ответы [ 5 ]

3 голосов
/ 26 апреля 2011

Есть несколько способов сделать это.Основы - это то, что вам нужно, чтобы XAML мог видеть вашу коллекцию.Вы можете сделать это неявным образом, установив его в свой DataContext.Если это единственное, что вы связываете, то это быстрый и грязный способ связывания.Это выглядело бы так:

public partial class MainWindow : Window

{
    public ObservableCollection<Directory> DirectoryList;

    public MainWindow()
    {
        InitializeComponent();

        DirectoryList = new ObservableCollection<Directory>();
        Directory _dirtemp = new Directory();
        _dirtemp.IKey = "1";
        _dirtemp.IValue = "Steve";
        DirectoryList.Add(_dirtemp);

        _dirtemp = new Directory();
        _dirtemp.IKey = "2";
        _dirtemp.IValue = "John";
        DirectoryList.Add(_dirtemp);


        DataContext=DirectoryList;

    }
}

Window x:Class="DataBindCombo.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:DataBindCombo"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
              ItemsSource="{Binding}"
              DisplayMemberPath="IValue"
              SelectedValuePath="IKey"
              >

Другой способ более сложный, но, вероятно, вы будете использовать его чаще.Для этого вам нужно представить свою коллекцию в вашем MainWindow как DependencyProperty, а затем привязать к этому значению.Это выглядело бы примерно так:

public partial class MainWindow : Window
    {
        public static DependencyProperty DirectoryListProperty =
            DependencyProperty.Register("DirectoryList",
            typeof(ObservableCollection<Directory>),
            typeof(MainWindow));

        public MainWindow()
        {
            InitializeComponent();
        }

        public ObservableCollection<Directory> DirectoryList
        {
            get { return (ObservableCollection<Directory>)base.GetValue(DirectoryListProperty); }
            set { base.SetValue(DirectoryListProperty, value); }
        }
    }

<Window x:Class="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" x:Name="mainWindow">
    <Grid>
        <ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
              ItemsSource=" {Binding ElementName=mainWindow, Path=DirectoryList}"
              DisplayMemberPath="IValue"
              SelectedValuePath="IKey"
              />

Это также не единственный способ сделать это таким образом.В целом, вместо создания списка непосредственно в элементе управления, вы должны создать модель представления.Шаблон MVVM является рекомендуемым способом создания вашей презентации, но мои примеры дают вам возможность получить функциональность там.Вы можете играть и экспериментировать с различными способами сделать это.Я обнаружил, что всегда есть несколько способов сделать что-то в WPF, и нужно найти тот, который лучше всего подходит для ситуации.

1 голос
/ 26 апреля 2011

Что вам нужно сделать, это установить DataContext ComboBox равным вашему ObservableCollection.

Код-за:

  public partial class MainWindow : Window
{
    private ObservableCollection<Directory> directoryList;

    public MainWindow()
    {
        InitializeComponent();

        directoryList = new ObservableCollection<Directory>();
        Directory _dirtemp = new Directory();
        _dirtemp.IKey = "1";
        _dirtemp.IValue = "Steve";
        directoryList.Add(_dirtemp);

        _dirtemp = new Directory();
        _dirtemp.IKey = "2";
        _dirtemp.IValue = "John";
        directoryList.Add(_dirtemp);

        this.comboBox1.DataContext = DirectoryList;
        //OR for the entire window you can simply do this.DataContext = DirectoryList;
    }

    public ObservableCollection<Directory> DirectoryList
    {
        get { return directoryList; }
    } 
}

public class Directory
{
    private string _ikey;
    public string IKey
    {
        get
        {
            return _ikey;
        }
        set
        {
            _ikey = value;
        }
    }
    private string _ivalue;
    public string IValue
    {
        get
        {
            return _ivalue;
        }
        set
        {
            _ivalue = value;
        }
    }

}

Xaml:

<Window x:Class="WpfApplication3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="84" Width="167">
<Grid>
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="12,12,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{Binding}"/>
</Grid>

Хотя, как уже отмечали другие, лучшим подходом будет использование шаблона проектирования Model-View-ViewModel. Это позволит отделить представление (часть xaml) от «бизнес-логики». Вот хороший пример того, как связать comboBox с помощью MVVM.

http://mark -dot-net.blogspot.com / 2009/03 / связывании-комбо-боксы-в-МОФ-с-mvvm.html

1 голос
/ 26 апреля 2011

Пути в привязке относятся к локальному DataContext, а не к содержащему окну. Вы не установили DataContext для своего Окна, поэтому у WPF нет объекта для поиска свойства DirectoryList.

С вашей текущей объектной моделью вам нужно установить this.DataContext = this; в конструкторе MainWindow. Теперь объектом MainWindow будет DataContext, и привязка DirectoryList будет разрешена для объекта MainWindow. (В долгосрочной перспективе лучше переместить модель данных в отдельный класс и установить для DataContext экземпляр этого класса, но это отдельная проблема.)

Кроме того, WPF может связываться только со свойствами, а не с полями. Ваш атрибут DirectoryList в настоящее время является полем; вам нужно будет поменять его на собственность.

0 голосов
/ 26 апреля 2011

Укажите привязку к вашему коду:

ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type Window}},Path=DirectoryList}"
0 голосов
/ 26 апреля 2011

Вам необходимо установить DataContext окна.Например, как это:

public MainWindow()
{
    InitializeComponent();
    DataContext = this;
     ....
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...