1
votes

I am developing a wpf application. here i have to populate 2nd combo box based on the first combo box selection.

my xaml as follows:

 <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>

When I save, I want to clear all data and show the form to allow fresh selection.

When I save, throws an error.

   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)

my view model code is as follows.

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

   }
}

I want to get the parameter value from combo box one and use that to populate to the second.

First time loading is file, when saving, the CategorySelected commnd expects a parameter, but it is assigned null. How to handle the null value in the RelayCommand....

1
The exception is thrown from your viewModel. Post the code of your ViewModels ...Omri Btian
You really need to provide the code for your SaveData method to receive help. In saying that, a null reference is a null reference. Stepping through your code with debugger should make the error very easy to fix.JuStDaN
@Omribitan, i have updated with the view model code. Thanks for responding my problemSNS
@JuStDaN.. Please check nowSNS

1 Answers

1
votes

It sound like you should use Master Details Pattern.

here are examples showing how correctly implement the pattern in wpf.
WPF Master Details MVVM Application
MSDN Article

ps:
dont forget to set IsSynchronizedWithCurrentItem="true"