WPF MVVM +如何将两个控件绑定到不同的属性?

时间:2016-04-20 13:59:59

标签: wpf mvvm data-binding

我有一个使用MVVM模式的WPF应用程序。

在用户控件上,我有两个DataGrid,它们的ItemsSource绑定到两个不同的属性。

其中一个DataGrid正确填充,但另一个不是。

我无法弄清楚绑定有什么问题。我已经尝试显式设置DataGrid的DataContext不起作用,但我不确定为什么我应该这样做,或者在哪里做。

我已经验证了检索数据的工作正常,因为我可以调试并查看数据,而DataGrid包含可点击的行,而且没有文字显示。

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>

名为LstCategories的DataGrid按预期工作,但LstItems是问题所在。

1 个答案:

答案 0 :(得分:1)

所以问题真的很傻。我想如果我展示了我的模型课程,大多数人会立即发现它。

我忘了在我的模型类

上添加getter和setter到我的属性

所以我有

public string ItemCode;

而不是:

public string ItemCode {get; set;}