在wpf应用程序中的第一个组合框选择更改中将数据填充到第二个组合框

时间:2013-09-25 05:34:39

标签: c# wpf parameters combobox relaycommand

我正在开发一个wpf应用程序。在这里,我必须根据第一个组合框选择填充第二个组合框。

我的xaml如下:

 <Grid Height="194" Width="486">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="82*" />
        <ColumnDefinition Width="404*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="72*" />
        <RowDefinition Height="122*" />
    </Grid.RowDefinitions>
    <Label Content="Category" Height="28" HorizontalAlignment="Left" Margin="13,36,0,0" Name="lblCategory" VerticalAlignment="Top" />
    <TextBox Height="23" HorizontalAlignment="Left" Margin="18,32,0,0" Name="txtScenario" VerticalAlignment="Top" Width="343" Text="{Binding Scenario_Desc}" Grid.Column="1" Grid.Row="1" />
    <Button Content="Save" Command="{Binding SaveData}" Height="23" HorizontalAlignment="Left" Margin="194,71,0,0" Name="btnSave" VerticalAlignment="Top" Width="75" Grid.Row="1" Grid.Column="1" />
    <Button Content="Reset" Command="{Binding ClearData}" Height="23" HorizontalAlignment="Left" Margin="286,71,0,0" Name="btnReset" VerticalAlignment="Top" Width="75" Grid.Row="1" Grid.Column="1" />
    <Label Content="Sub Category" Height="28" HorizontalAlignment="Left" Margin="13,70,0,0" Name="lblSubCategory" VerticalAlignment="Top" Grid.RowSpan="2" Grid.ColumnSpan="2" />
    <ComboBox Height="23" HorizontalAlignment="Left" Margin="18,36,0,0" Name="cboCategory" VerticalAlignment="Top" Width="343" 
             ItemsSource="{Binding Path=Category}"
             DisplayMemberPath="Category_Desc"
             SelectedValuePath="Category_Id"
             SelectedValue="{Binding Path=Category_Id,  Mode=TwoWay}"
             SelectedIndex="0"
             Text="{Binding Category_Desc}" Grid.Column="1">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="SelectionChanged">
                <i:InvokeCommandAction Command="{Binding CategorySelected}"
                                   CommandParameter="{Binding SelectedValue, ElementName=cboCategory}"/>
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </ComboBox>



    <Label Content="Scenario" Grid.ColumnSpan="2" Height="28" HorizontalAlignment="Left" Margin="12,32,0,0" Name="lblScenario" VerticalAlignment="Top" Grid.Row="1" />
    <ComboBox  Height="23" HorizontalAlignment="Left" VerticalAlignment="Top" Width="343" Grid.Column="1" Grid.RowSpan="2" ItemsSource="{Binding Path=SubCategory}" Margin="18,70,0,0" Name="cboSubCategory" 
               DisplayMemberPath="Sub_Category_Desc"
               SelectedValue="{Binding Path=Sub_Category_Id}" 
               SelectedValuePath="Sub_Category_Id" 
               Text="{Binding Sub_Category_Desc}"  />
</Grid>

当我保存时,我想清除所有数据并显示表单以允许新选择。

当我保存时,抛出错误。

   System.NullReferenceException was unhandled
   Message=Object reference not set to an instance of an object.
   StackTrace: RelayCommand`1.CanExecute(Object parameter) .....
   at System.Windows.Interactivity.InvokeCommandAction.Invoke(Object parameter)

我的视图模型代码如下。

namespace MYOWN
{
public class ScenarioViewModel:BaseViewModel
{
    private ScenarioModel scenarioModel;
    public event EventHandler<ModelViewEventArgs> Reset = delegate { };
    ObservableCollection<CategoryViewModel> category = new ObservableCollection<CategoryViewModel>();
    ObservableCollection<SubCategoryViewModel> subCategory = new ObservableCollection<SubCategoryViewModel>();

    public ScenarioViewModel()
    {
        scenarioModel = new ScenarioModel();
        scenarioModel.isNew = true;
        PopulateCategory();
     }

    public ScenarioViewModel( ScenarioModel scenario)
    {
        this.scenarioModel = scenario;
        PopulateCategory();

    }

    private void PopulateCategory()
    {
        List<BaseModel> categoryModelList = DataManger.GetData((BaseModel)new CategoryModel());

        foreach (CategoryModel cat in categoryModelList)
        {
            category.Add(new CategoryViewModel(cat));
        }

    }

    private void PopulateSubCategory(int category_id)
    {
        //clear the exsisting list
        subCategory.Clear();

        SubCategoryModel model = new SubCategoryModel();
        model.category_id = category_id;

        //get the sub Category data for given category
        List<BaseModel> subCategoryModelList = DataManger.GetData(model);

        //populate the collection
        foreach (SubCategoryModel cat in subCategoryModelList)
        {
            subCategory.Add(new SubCategoryViewModel(cat));
        }

    }

    public ObservableCollection<SubCategoryViewModel> SubCategory
    {
        get { return subCategory; }
        set { subCategory = value; }
    }
    public ObservableCollection<CategoryViewModel> Category
    {
        get { return category; }
        set { category = value; }
    }

    public ScenarioModel ScenarioModel
    {
        get { return scenarioModel; }
        set { scenarioModel = value; }
    }


    public Int32 Scenario_Id
    {
        get
        {
            return scenarioModel.scenario_id;
        }

        set
        {
            scenarioModel.scenario_id = value;
            RaisePropertyChanged("Scenario_Id");
        }
    }

    public string Scenario_Desc
    {
        get
        {
            return scenarioModel.scenario_desc;
        }

        set
        {
            scenarioModel.scenario_desc = value;
            RaisePropertyChanged("Scenario_Desc");
        }
    }

    public Int32 Sub_Category_Id 
    {
        get
        {
            return scenarioModel.sub_category_id;
        }

        set
        {
            scenarioModel.sub_category_id = value;
            RaisePropertyChanged("Sub_Category_Id");
        }
    }

    string sub_category_desc;
    public string Sub_Category_Desc
    {
        get
        {
            return sub_category_desc;
        }

        set
        {
            sub_category_desc = value;
            RaisePropertyChanged("Sub_Category_Desc");
        }
    }

    int category_id;
    public int Category_Id
    {
        get
        {
            return category_id;
        }

        set
        {
            category_id = value;
            RaisePropertyChanged("Category_Id");
        }
    }

    string category_desc;
    public string Category_Desc
    {
        get
        {
            return category_desc;
        }

        set
        {
            category_desc = value;
            RaisePropertyChanged("Category_Desc");
        }
    }



    #region Commands


    protected void SelectSubCategoryDataExecute(int param=0)
    {
        PopulateSubCategory(param);
    }

    protected bool CanSelectSubCategoryDataExecute(int param=0)
    {
        return true;
    }


    public ICommand CategorySelected
    {
        get
        {
            return new RelayCommand<int>(SelectSubCategoryDataExecute, CanSelectSubCategoryDataExecute);
        }
    }


    protected override void SaveMasterDataExecute()
    {
        DataManger.Save((BaseModel)scenarioModel);
        //Clear once Save the data
        OnReset();
    }

    protected override bool CanSaveMasterDataExecute()
    {
        return true;
    }


    protected void OnReset()
    {
        ScenarioViewModel viewModel = new ScenarioViewModel();
        if (viewModel != null)
        {
            Reset(this, new ModelViewEventArgs(viewModel));
        }
    }

    protected override void ResetDataExecute()
    {
        OnReset();
    }

    protected override bool CanResetDataExecute()
    {
        return true;
    }

    #endregion

   }
}

我想从组合框1中获取参数值,并使用它填充到第二个。

第一次加载是文件,保存时,CategorySelected引用需要一个参数,但是它被赋值为null。如何处理RelayCommand中的空值....

1 个答案:

答案 0 :(得分:1)

听起来你应该使用Master Details Pattern。

这里是一些示例,展示了如何在wpf中正确实现模式 WPF Master Details MVVM Application
MSDN Article

PS:
别忘了设置IsSynchronizedWithCurrentItem="true"