2013-09-25 3 views
1

wpf 응용 프로그램을 개발 중입니다. 여기서는 첫 번째 콤보 상자 선택을 기반으로 두 번째 콤보 상자를 채워야합니다.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 

    } 
} 

콤보 상자에서 매개 변수 값을 가져 와서 두 번째 입력란으로 채 웁니다.

첫 번째 로딩은 파일이며 저장시 CategorySelected 명령은 매개 변수를 필요로하지만 null이 할당됩니다. RelayCommand에서 null 값을 처리하는 방법 ....

+2

을 발생합니다 설정하는 것을 잊지 말아. ViewModels 코드를 게시하십시오 ... –

+0

정말 SaveData 메서드에 대한 코드를 제공하여 도움을 받아야합니다. 말하자면, null 참조는 null 참조입니다. 디버거를 사용하여 코드를 실행하면 오류를 매우 쉽게 수정해야합니다. – JuStDaN

+0

@Omribitan,보기 모델 코드를 업데이트했습니다. 내 문제에 대한 답변을 주셔서 감사합니다 – SNS

답변

1

마스터 세부 정보 패턴을 사용해야하는 것처럼 들립니다.

은 wpf에서 패턴을 올바르게 구현하는 예를 보여줍니다.
WPF Master Details MVVM Application
MSDN Article

PS :
는 예외가 당신의 ViewModel에서 IsSynchronizedWithCurrentItem="true"