2015-12-01 2 views
1

Я пытаюсь добавить кнопки в UserControl. Я должен следовать шаблону MVVM. Я создал класс DeviceButton с разными установками/get и конструктором. В viewmodel, используемом как datacontext, является ObservableCollection и get-method для коллекции. Я связал сборку с источником ItemsControl и попытался добавить шаблон. Наверное, я что-то упустил, потому что кнопки не будут загружаться.Добавление кнопок в WPF из ObservableCollection с использованием шаблона MVVM

UserControl добавлен во вкладку (с использованием dragablz), которая также является частью ObservableCollection, также добавленной во время выполнения (это работает отлично). Идея состоит в том, что на вкладке есть список кнопок, которые должны быть созданы во время выполнения, где список извлекается из веб-службы - поэтому кнопки должны добавляться динамически/программно. Обзор - это только первая вкладка - шаблон для каждой вкладки (отражающий извлеченные элементы) реализуется при работе кнопок. На данный момент я просто добавляю тестовую кнопку в коллекцию, но, как сказано, это не будет отображаться. Что мне не хватает?

У меня есть Overview.xaml файл:

<UserControl // attributes omitted to save spaces... ask if needed> 

<StackPanel> 
    <Border> 
     <TextBlock FontSize="16" FontWeight="Bold" TextWrapping="WrapWithOverflow" 
        TextAlignment="Center" HorizontalAlignment="Center" 
        Foreground="{DynamicResource AccentColorBrush}"> 
      Welcome to Greenhouse App 
     </TextBlock> 
    </Border> 

    <ItemsControl ItemsSource="{Binding DeviceButtons}"> 
     <ItemsControl.ItemTemplate> 
      <DataTemplate DataType="{x:Type vmodel:DeviceButton}"> 
       <Button Width="50" Height="50" Margin="10 10 0 0" Command="{Binding OpenTab}" 
         CommandParameter="{Binding DeviceType}" HorizontalAlignment="Left" 
         VerticalAlignment="Top" Style="{DynamicResource SquareButtonStyle}"> 
        <StackPanel> 
         <Image Source="{Binding ImageUrl}" /> 
        </StackPanel> 
       </Button> 
      </DataTemplate> 
     </ItemsControl.ItemTemplate> 
    </ItemsControl> 

    // Manually added test button... 
    <Button x:Name="windMill" HorizontalAlignment="Left" Margin="10,0,0,0" 
      VerticalAlignment="Top" Width="50" Height="50" 
      Command="{Binding OpenTab}" FontFamily="Segoe Ui" 
      Style="{DynamicResource SquareButtonStyle}"> 
     <StackPanel> 
      <Image Source="/Greenhouse;component/Icons/Windmill.png" /> 
     </StackPanel> 
    </Button 
</StackPanel> 

Я пытаюсь добавить ObservableCollection типа DeviceButton, коллекция _deviceButtons (переплетено, как ItemsSource к ItemsControl)

Элементы tabList работают только для поиска, и я могу вручную добавить больше, если это необходимо (позже они будут добавлены через команду OpenNewTab, которая должна быть привязана к кнопкам)

DeviceButton файл:

public class DeviceButton 
{ 
    private readonly string _content; 
    private readonly string _deviceType; 
    private readonly string _imageUrl; 

    public DeviceButton(string content, string deviceType, string imageUrl) 
    { 
     _content = content; 
     _deviceType = deviceType; 
     _imageUrl = imageUrl; 
    } 

    public string Content 
    { 
     get { return _content; } 
    } 

    public string DeviceType 
    { 
     get { return _deviceType; } 
    } 

    public string ImageUrl 
    { 
     get { return _imageUrl; } 
    } 
} 

Коллекция находится в файле ViewModel, MainWindowViewModel.cs:

public class MainWindowViewModel : ViewModelBase, INotifyPropertyChanged 
{ 
    public ICommand OpenTab { get; set; } 

    private string tabControl { get; set; } = "0"; 
    private IInterTabClient _interTabClient; 
    private ObservableCollection<TabContent> _tabContents = new ObservableCollection<TabContent>(); 
    private ObservableCollection<DeviceButton> _deviceButtons = new ObservableCollection<DeviceButton>(); 

    public MainWindowViewModel() 
    { 
     _interTabClient = new MyInterTabClient(); 

     DeviceButtons.Add(new DeviceButton("Windturbine", "windturbine", "/Greenhouse;component/Icons/Windmill.png")); 

     TabContents.Add(new TabContent("Overview", new Overview())); 

     OpenTab = new RelayCommand<object>(OpenNewTab); 
    } 

    private void OpenNewTab(object obj) 
    { 
     MessageBox.Show("Yo"); // Not yet implemented 
     RaisePropertyChanged(() => tabControl); 
    } 

    public ObservableCollection<TabContent> TabContents 
    { 
     get { return _tabContents; } 
    } 

    public ObservableCollection<DeviceButton> DeviceButtons 
    { 
     get { return _deviceButtons; } 
    } 

    public IInterTabClient InterTabClient 
    { 
     get { return _interTabClient; } 
    } 
} 

Кнопки не загружаются при запуске программы (только «тест» кнопка добавлена ​​вручную в WPF).

UserControl, Обзор, считается закладка в другой Controls.Metrowindow, MainWindow.xaml:

<Window.Resources> 
    <Style TargetType="{x:Type dragablz:TabablzControl}"> 
     <Setter Property="CustomHeaderItemTemplate"> 
      <Setter.Value> 
       <DataTemplate DataType="{x:Type viewmodel:TabContent}"> 
        <TextBlock Text="{Binding Header}" /> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
     <Setter Property="ContentTemplate"> 
      <Setter.Value> 
       <DataTemplate DataType="{x:Type viewmodel:TabContent}"> 
        <ContentPresenter Margin="4" Content="{Binding Content}" /> 
       </DataTemplate> 
      </Setter.Value> 
     </Setter> 
    </Style> 
</Window.Resources> 

<dragablz:TabablzControl SelectedIndex="{Binding tabControl}" ItemsSource="{Binding TabContents}" x:Name="InitialTabablzControl" Margin="4 0 4 4"> 
    <dragablz:TabablzControl.InterTabController> 
     <dragablz:InterTabController InterTabClient="{Binding MyInterTabClient}" /> 
    </dragablz:TabablzControl.InterTabController> 
</dragablz:TabablzControl> 

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

+1

Я предложил бы использовать такой инструмент, как [Snoop] (https://snoopwpf.codeplex.com/), чтобы проверить ваш DataContext является то, что вы ожидаете ... Я подозреваю, 'DataContext' устанавливается в объект' TabContent', который не имеет свойства 'DeviceButtons'. – Rachel

+0

Вы пробовали ItemsSource = "{Binding Path = DataContext.TabContents, RelativeSource = {RelativeSource AncestorLevel = 1, AncestorType = {x: Type Window}, Mode = FindAncestor}}"? И да, вы должны использовать Snoop в таких случаях. – galakt

+0

@galakt Спасибо, что сделал. Если вы сделаете ответ, я буду отмечать его как правильный ответ. – eli

ответ

1

Проблема была в связывании

ItemsSource="{Binding Path=DataContext.TabContents, 
       RelativeSource={RelativeSource AncestorLevel=1, 
       AncestorType={x:Type Window}, Mode=FindAncestor}}" 
+0

Просто небольшое замечание: я использовал 'DataContext.DeviceButtons' вместо' TabContents' – eli

1

Я подозреваю, что DataContext создается на TabContent объект, который не имеет DeviceButtons свойство

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

+0

Я дал вам голосование, но мои голоса не являются публичными, так как моя собственная репутация еще недостаточно высока. – eli

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