2016-01-16 3 views
0

Я пришел из тяжелой среды Linux, где написал большинство моих инструментов на Python, но теперь я в тяжелой среде с Windows, и мне нужно поделиться своими инструментами с моей командой, а некоторые быть GUI, поэтому я пытаюсь изучить C#/WPF. Я запутался в привязке данных к ObservableCollection в коде позади. Я могу заставить его работать, но я не понимаю , почему, что беспокоит меня.C# и WPF привязка данных к ObservableCollection

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

XAML:

<ListView x:Name="lvUrlList" HorizontalAlignment="Left" Height="441" Margin="15,62,0,0" VerticalAlignment="Top" Width="486" SelectionChanged="listView_SelectionChanged" ItemsSource="{Binding Path=urlList, ElementName=MainWindow1}"> 
     <ListView.ItemTemplate> 
      <DataTemplate> 
       <WrapPanel> 
        <TextBlock Text="{Binding domain}"/> 
       </WrapPanel> 
      </DataTemplate> 
     </ListView.ItemTemplate> 
    </ListView> 

Код Behind:

namespace ReferalScraper 
{ 
    /// <summary> 
    /// Interaction logic for MainWindow.xaml 
    /// </summary> 
    public partial class MainWindow : Window 
    { 

     //public ObservableCollection<Url> urlList { get; set; } // Method 1 
     public ObservableCollection<Url> urlList = new ObservableCollection<Url>(); // Method 2 
     public MainWindow() 
     { 
      // urlList = new ObservableCollection<Url>(); // Method 1 
      InitializeComponent(); 
      urlList.Add(new Url() { domain = "www.test1.com" }); 

     } 

     public class Url 
     { 
      public string domain { get; set; } 

     } 

     private void button_Click(object sender, RoutedEventArgs e) 
     { 

      urlList.Add(new Url() { domain = "www.test2.com" }); 
      urlList.Add(new Url() { domain = "www.test3.com" }); 

     } 
    } 
} 

Неофициальный метод создания и создания экземпляра ObservableCol разночтение не работает, код компилируется, но я получаю ошибку на выходе:

System.Windows.Data Error: 40 : BindingExpression path error: 'urlList' property not found on 'object' ''MainWindow' (Name='MainWindow1')'. BindingExpression:Path=urlList; DataItem='MainWindow' (Name='MainWindow1'); target element is 'ListView' (Name='lvUrlList'); target property is 'ItemsSource' (type 'IEnumerable') 

Что я понимаю, что это означает, что он не может найти объект urlList в MainWindow. Но я не понимаю, почему он не может его найти.

Если я включаю в способе 1 и раскомментируйте следующие две строки (и закомментируйте «Метод 2» часть) она отлично работает:

public ObservableCollection<Url> urlList { get; set; } 
... 
public MainWindow(){ 
     urlList = new ObservableCollection<Url>() 

Почему декларирует ObserverableCollection с { get; set } необходимой? Я не совсем понимаю, почему я не могу просто создать экземпляр ObservableCollection как пустой ObserverableCollection, как я есть в методе 2.

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

У меня такое чувство, что это понимание на C#, которое мне не хватает.

ответ

3

Синтаксис { get; set; } определяет ваш uriList как собственности (auto-implemented property, в данном случае). Без этого uriList - это просто поле .

Связывание данных WPF не может связываться с полями. См. this related question для дальнейшего обсуждения того, почему это так.

Обычно в C# поля обычно не отображаются как общедоступные, предпочтительными являются свойства. Это позволяет вам изменить реализацию get/set, если это необходимо. В стороне, соглашение об именах для свойств - PascalCased (так UriList, а не uriList).

+0

Спасибо, я буду считать это и делать больше чтения на полях против Свойства, у меня такое чувство, что я не знаю никаких знаний. Могу ли я определить и создать экземпляр объекта сразу? Есть ли причина, по которой мне нужно позже вызвать 'new ObserverableCollection ' part? – z0dSki

+0

См. Ссылку на автоматически реализованные свойства. Если вы используете C# 6 (если вы используете VS 2015, вы будете), вы можете сделать это в одной строке, аналогично инициализации поля. Вы также можете опустить 'set'. –

+0

О, мальчик, я был ** очень плотным, и это просто осенило меня. MainWindow - это класс, в котором я подвергаюсь этому свойству, поэтому, конечно, ничего не существует, если ничего не видно! Это был огромный момент. Еще раз спасибо, ресурсы разъяснили это, и у меня есть хорошее чтение. – z0dSki

0

используется ElementName связывания, когда вы пытаетесь получить свойство вы связывающую, от собственности другого FramworkElement «s, что не тот случай,

вам нужно первым: правильно установить DataContext либо из отделенного кода в конструкторе MainWindow:

this.DataContext=this; 

или из Xaml в Window

DataContext="{Binding RelativeSource={RelativeSource Self}}" 

Тогда объявляю вам UriList как свойство, поэтому он может быть использован с обязательным

private ObservableCollection<Url> _uriList = new ObservableCollection<Url() 
    { 
     new Url() { domain = "www.test2.com" } 
    }; 

    public bool UrlList 
    { 
     get 
     { 
      return _uriList; 
     } 

     set 
     { 
      if (_uriList == value) 
      { 
       return; 
      } 

      _uriList = value; 

     } 
    } 

и изменить ваши привязки к следующему:

ItemsSource="{Binding UrlList} 
Смежные вопросы