2016-04-20 4 views
0

Ich habe eine WPF-Anwendung mit MVVM-Muster.WPF MVVM + Wie zwei Steuerelemente an verschiedene Eigenschaften gebunden haben?

Auf einem Benutzersteuerelement habe ich zwei DataGrids, deren ItemsSource an zwei verschiedene Eigenschaften gebunden ist.

Eines der DataGrids ist korrekt ausgefüllt, das andere nicht.

Ich kann nicht herausfinden, was mit der Bindung falsch ist. Ich habe versucht, den DataContext des DataGrids explizit einzustellen, aber ich bin mir nicht sicher, warum ich das tun sollte oder wo ich es tun soll.

Ich habe verifiziert, dass das Abrufen der Daten funktioniert, da ich die Daten debuggen und sehen kann, und das DataGrid hat Zeilen, die "anklickbar" sind, da nur kein Text angezeigt wird.

AssignItemsToCategoryViewModel.cs

/// <summary> 
    /// Describes the name that will be used for the menu option 
    /// Implemented from IPageViewModel 
    /// </summary> 
    public string Name 
    { 
     get { return "Assign Items To Categories "; } 

    } 

    #region Categories 
    private CategoryModel _currentCategory; 
    public CategoryModel CurrentCategory 
    { 
     get { return _currentCategory; } 
     set 
     { 
      _currentCategory = value;    
      OnPropertyChanged("CurrentCategory"); 
     }  
    } 

    public ObservableCollection<CategoryModel> Categories = new ObservableCollection<CategoryModel>(); 

    public RelayCommand GetCategoriesRelay; 

    public AssignItemsToCategoryViewModel() 
    { 
     CurrentCategory = new CategoryModel(); 
     CurrentStockItem = new StockItemModel(); 
    } 

    #region Get Categories Command 
    /// <summary> 
    /// The interface command 
    /// to run the get GetCategories method 
    /// </summary> 
    public ICommand GetCategoriesCommand 
    { 
     get 
     { 
      GetCategoriesRelay = new RelayCommand(p => GetCategories(), 
       p => CanGetCategories()); 

      return GetCategoriesRelay; 
     } 
    } 

    /// <summary> 
    /// Checks whether the GetCategories command can be run 
    /// </summary> 
    /// <returns>True or False</returns> 
    private bool CanGetCategories() 
    { 
     return true; 
    } 

    /// <summary> 
    /// Method to fetch the categories 
    /// </summary> 
    private void GetCategories() 
    { 
     Categories = CurrentCategory.GetCategories(); 
     ReceivedCategories = Categories; 

     if (Categories.Any()) 
      SelectedIndex = 0; 

    } 

    #endregion 


    /// <summary> 
    /// Gets or sets the DataGrid's selected index 
    /// Used to set the index to 0 if any categories exist. 
    /// </summary> 
    private int _selectedIndex; 
    public int SelectedIndex 
    { 
     get { return _selectedIndex; } 
     set 
     { 
      _selectedIndex = value; 
      OnPropertyChanged("SelectedIndex"); 
     } 
    } 



    /// <summary> 
    /// Gets or sets the collection of received categories 
    /// </summary> 
    public ObservableCollection<CategoryModel> ReceivedCategories 
    { 
     get { return Categories; } 

     set 
     { 
      Categories = value; 
      OnPropertyChanged("ReceivedCategories"); 
     } 
    } 
    #endregion 

    #region Stock Items 

    private StockItemModel _currentStockItem; 
    public StockItemModel CurrentStockItem 
    { 
     get { return _currentStockItem; } 
     set 
     { 
      _currentStockItem = value; 
      OnPropertyChanged("CurrentStockItem"); 
     } 
    } 

    public ObservableCollection<StockItemModel> StockItems = new ObservableCollection<StockItemModel>(); 

    public RelayCommand GetStockItemsRelay; 
    public RelayCommand LinkItemRelay; 
    public RelayCommand UnlinkItemRelay; 


    #region Get Stock Items Command 

    /// <summary> 
    /// The interface command 
    /// to run the get GetStockItems method 
    /// </summary> 
    public ICommand GetStockItemsCommand 
    { 
     get 
     { 
      GetStockItemsRelay = new RelayCommand(p => GetStockItems(), 
       p => CanGetStockItems()); 

      return GetStockItemsRelay; 
     } 
    } 

    /// <summary> 
    /// Checks whether the GetStockItems command can be run 
    /// </summary> 
    /// <returns>True or False</returns> 
    private bool CanGetStockItems() 
    { 
     return true; 
    } 

    /// <summary> 
    /// Method to fetch the stock items 
    /// </summary> 
    private void GetStockItems() 
    { 
     StockItems = CurrentStockItem.GetStockItems(); 
     ReceivedStockItems = StockItems; 

     if (ReceivedStockItems.Any()) 
      SelectedStockItemIndex = 0; 

    } 

    #endregion 

    /// <summary> 
    /// Gets or sets the Stock Items DataGrid's selected index 
    /// Used to set the index to 0 if any stock items exist. 
    /// </summary> 
    private int _selectedStockItemIndex; 
    public int SelectedStockItemIndex 
    { 
     get { return _selectedStockItemIndex; } 
     set 
     { 
      _selectedStockItemIndex = value; 
      OnPropertyChanged("SelectedStockItemIndex"); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the CurerntStockItem Id 
    /// </summary> 
    public long? StockLinkId 
    { 
     get { return CurrentStockItem.StockLink; } 
     set 
     { 
      CurrentStockItem.StockLink = value; 
      OnPropertyChanged("StockLinkId"); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the CurrentStockItem ItemCode 
    /// </summary> 
    public string ItemCode 
    { 
     get 
     { 
      return CurrentStockItem.ItemCode; 
     } 
     set 
     { 
      CurrentStockItem.ItemCode = value; 

      OnPropertyChanged("ItemCode"); 
     } 
    } 

    /// <summary> 
    /// Gets or sets the collection of received categories 
    /// </summary> 
    public ObservableCollection<StockItemModel> ReceivedStockItems 
    { 
     get { return StockItems; } 

     set 
     { 
      StockItems = value; 
      OnPropertyChanged("ReceivedStockItems"); 
     } 
    } 

    #endregion 
} 

AssignItemsToCategoryView.xaml

<UserControl x:Class="SalesLinker.View.AssignItemsToCategoryView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"  
    mc:Ignorable="d" 
    d:DesignHeight="300" d:DesignWidth="600" Background="White"> 

<i:Interaction.Triggers> 
    <i:EventTrigger EventName="Loaded"> 
     <i:InvokeCommandAction Command="{Binding GetCategoriesCommand}" /> 
     <i:InvokeCommandAction Command="{Binding GetStockItemsCommand}" /> 
    </i:EventTrigger> 
</i:Interaction.Triggers> 

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="45"/> 
     <RowDefinition Height="*"/> 
    </Grid.RowDefinitions> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="250"/> 
     <ColumnDefinition Width="100"/> 
     <ColumnDefinition Width="*"/> 
    </Grid.ColumnDefinitions> 


    <Border Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" 
      Style="{StaticResource MainBorderStyle}" > 

     <HeaderedContentControl x:Name="ItemsList" 
           Style="{StaticResource MainHCCStyle}" 
           Header="Items"> 

      <DataGrid x:Name="LstItems" Grid.Column="0" Grid.Row="1" AutoGenerateColumns="false" IsReadOnly="True" 
       ItemsSource="{Binding Path=ReceivedStockItems, Mode=TwoWay}" 
       HorizontalScrollBarVisibility="Disabled" GridLinesVisibility="None" 
       CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="True" Background="White" 
       SelectedIndex="{Binding Path=SelectedStockItemIndex}" > 
       <DataGrid.Columns> 
        <DataGridTextColumn Binding="{Binding Path=ItemCode}" IsReadOnly="True" Header="Item Code" Width="300" /> 
       </DataGrid.Columns> 
      </DataGrid> 
     </HeaderedContentControl> 
    </Border> 

    <DockPanel Grid.Row="1" Grid.Column="1"> 
     <StackPanel VerticalAlignment="Center" > 

      <StackPanel.Resources> 
       <Style TargetType="{x:Type Button}"> 
        <Setter Property="Margin" Value="0,10,0,0"/> 
       </Style> 
      </StackPanel.Resources> 
       <Button Command="{Binding LinkItemCommand}" Height="50" Width="50" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" 
        CommandParameter="{Binding ElementName=TbDescription, Path=Text}"> 
       <Image Source="/Images/RightArrow.png"/> 
      </Button> 

      <Button Command="{Binding UnlinkItemCommand}" Height="50" Width="50" Background="Transparent" BorderThickness="0" BorderBrush="Transparent" 
         CommandParameter="{Binding SelectedItem.CategoryID, ElementName=LstCategories, Mode=OneWay }" > 
       <Image Source="/Images/LeftArrow.png"/> 
      </Button> 

     </StackPanel> 
    </DockPanel> 


    <Border Grid.Column="2" Grid.Row="0" Grid.RowSpan="2" VerticalAlignment="Stretch" 
      Style="{StaticResource MainBorderStyle}" > 

     <HeaderedContentControl x:Name="CategoryItems" 
           Style="{StaticResource MainHCCStyle}" 
           Header="Categories"> 

      <DataGrid x:Name="LstCategories" Grid.Column="0" Grid.Row="1" AutoGenerateColumns="false" IsReadOnly="True" 
       ItemsSource="{Binding Path=ReceivedCategories, Mode=TwoWay}" 
       HorizontalScrollBarVisibility="Disabled" GridLinesVisibility="None" 
       CanUserAddRows="False" CanUserDeleteRows="False" CanUserSortColumns="True" Background="White" 
       SelectedIndex="{Binding Path=SelectedIndex}"> 


       <DataGrid.Columns> 
        <DataGridTextColumn Binding="{Binding Path=Description}" IsReadOnly="True" Header="Description" Width="300" /> 
       </DataGrid.Columns> 
      </DataGrid> 
     </HeaderedContentControl> 
    </Border> 

</Grid> 

Die Datagrid genannt LstCategories wie erwartet funktioniert, aber LstItems ist das Problem.

+3

Es gibt zu viel Material in Ihrer Frage für ich durchkämmen, um zu sehen, wo das Problem ist. Unterstützen Sie uns in Zukunft bei der Erstellung einer minimalen Version Ihres Codes, die Ihr Problem veranschaulicht. 70% der Zeit, die gerade das tun, werden Ihre Frage beantworten, wenn Sie Ihren Fehler herausfinden (protip: es ist im Heuhaufen des ganzen anderen Codes verborgen). Außerdem sollte das Ausgabefenster Bindungsfehler aufweisen. Überprüfe sie? Wenn nicht, suchen Sie nach Debugging-Binding-Fehlern. Schließlich, Snoop erhalten und überprüfen Sie Ihre Bindungen zur Laufzeit. Das hilft manchmal auch. – Will

+1

Dank Will, Snoop hat mir geholfen, meinen so dummen Fehler zu finden. – Neill

+0

Das ist großartig. Ich habe deinen Code durchgesehen und etwas so Offensichtliches gesehen, aber für die Zeit, die ich hatte, war es einfach zu viel. Es ist wirklich sehr wichtig, dass Sie Ihren Code paaren, wenn Sie eine Frage stellen. – Will

Antwort

1

Also das Problem war wirklich albern. Ich denke, wenn ich meine Modellklasse gezeigt hätte, hätte die Mehrheit der Leute es sofort entdeckt.

Ich habe vergessen, den Getter und Setter meiner Eigenschaft auf meiner Modellklasse

So hatte ich

public string ItemCode; 

statt hinzuzufügen:

public string ItemCode {get; set;} 
Verwandte Themen