2013-05-01 4 views
0

Я новичок в WPF. У меня есть Listview, и я хочу отобразить более usercontrol.WPF Listview binding userControl property

Я использовал ItemTemplate.

ListView, как это:

<ListView HorizontalAlignment="Stretch" Margin="0,40,0,0" Name="listView1" VerticalAlignment="Stretch" 
       ItemTemplate="{StaticResource DriveUserControlDataTemplate}" > 
     <ListView.ItemsPanel> 
      <ItemsPanelTemplate> 
       <WrapPanel Width="{Binding (FrameworkElement.ActualWidth), RelativeSource={RelativeSource AncestorType=ScrollContentPresenter}}" 
           ItemWidth="{Binding (ListView.View).ItemWidth, RelativeSource={RelativeSource AncestorType=ListView}}" 
           MinWidth="{Binding ItemWidth, RelativeSource={RelativeSource Self}}" 
           ItemHeight="{Binding (ListView.View).ItemHeight, RelativeSource={RelativeSource AncestorType=ListView}}" /> 
      </ItemsPanelTemplate> 
     </ListView.ItemsPanel> 
    </ListView> 


    <DataTemplate x:Key="DriveUserControlDataTemplate" > 
     <StackPanel Margin="10"> 
      <c:DriveUserControl Drive="{Binding Name}" EventAdd="DriveUserControlAdd_Click"> 
      </c:DriveUserControl > 
     </StackPanel> 
    </DataTemplate> 

и я хочу связать UserControls этим кодом:

listView1.ItemsSource = DriveInfo.GetDrives() 
       .Where(item => item.IsReady && item.DriveType == DriveType.Removable) 
       .ToList(); 

класса DriveInfo имеет свойство с именем Name

Любой один скажите мне, почему это не связывались?

ответ

0

Основным методом реализации WPF является MVVM (Model View ViewModel), а не код. Что вам нужно сделать, так это реализовать шаблон разработки MVVM. Могу ли я предложить вам начать с чтения одной из многих статей в Интернете о MVVM, http://msdn.microsoft.com/en-us/magazine/dd419663.aspx

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

Создайте класс и назовите его MainWindowViewModel и реализуйте интерфейс INotifyPropertyChanged. После того, как вы сделали это, выполните событие PropertyChanged. На данный момент мне нравится обманывать и писать себе вспомогательный метод, чтобы поднять это событие для меня, когда меняются свойства.

public class MainWindowViewModel : INotifyPropertyChanged { 
    public event PropertyChangedEventHandler PropertyChanged; 

    private void raisePropertyChanged(string propertyName) { 
    if (PropertyChanged != null) PropretyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Итак, на данном этапе у вас должно быть что-то, что показано выше. Это ViewModel.

Следующим шагом является создание свойств, которые вы хотите открыть для пользовательского интерфейса, представления. В вашем случае вы хотите указать диски, доступные на вашем компьютере. Поэтому нам нужно создать ObservableCollection строковых значений следующим образом.

private ObservableCollection<string> _drives = new ObservableCollection<string>(); 
public ObservableCollection<string> Drives { 
    get { return _drives; } 
    set { 
    _drives = value; 
    this.raisePropertyChanged("Drives"); 
    } 
} 

ОК со мной до сих пор? Итак, теперь у нас есть модель представления и пустой список строковых значений. УДИВИТЕЛЬНЫЙ ХУХ? Следующий шаг - заполнить список строк «Диски», поэтому мы пишем простой метод Init в классе.

public void Init() { 
    this.Drives = new ObservableCollection<string>(DriveInfo.GetDrives() 
       .Where(item => item.IsReady && item.DriveType == DriveType.Removable) 
       .ToList()); 
} 

Давайте сейчас оставим код в покое, и теперь мы обращаем наше внимание на представление (ваш пользовательский интерфейс). В пользовательском интерфейсе вам необходимо определить пространство имен, в котором находится класс ViewModel. Это помещается в первый элемент xaml в вашем окне.

xmlns:vms="clr-namespace:applicationNameSpace;assembly=applicationAssemblyName" 

Не забудьте заменить имя приложенияSame и ApplicationAssemblyName на правильные значения.

Далее мы объявляем класс ViewModel в ресурсах вашего окна.

<Window.Resources> 
    <vms:MainWindowViewModel x:Key="mainWindowVms"/> 
</Window.Resources> 

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

MainWindowViewModel mainWindowVms = Resources["mainWindowVms"] as MainWindowViewModel; 
mainWindowVms.Init(); 

Таким образом, это оставляет только одну последнюю вещь, которая отвечает на ваш вопрос: «Почему это не связано?». Хорошо, потому что ItemSource - это свойство, которое должно быть привязано к свойству из ViewModel. В других словах он использует интерфейс INotifyPropertyChanged, чтобы уведомить поток пользовательского интерфейса, что было внесено изменение объекту, к которому он привязан. Привязка к коду за винами поражения WPF. Поэтому, чтобы получить привязку, вы просто указываете привязку в своем xaml.

<ListView ItemsSource="{Binding Source={StaticResource mainWindowVms}, Path=Drives"/> 

Таким образом, у вас есть вид модели беспокоиться о состоянии и население вашего списка и ваш UI просто делает то, что он сказал.

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

+0

Большое спасибо –

+0

Нет проблем. Надеюсь, ответ подходит. Пожалуйста, отметьте как можно решить, если это исправит вашу проблему. – sepai

Смежные вопросы