Заполнение данных во втором поле со списком при изменении выбора первого поля со списком в приложении 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....
1 ответ
Похоже, вы должны использовать шаблон Master Details.
Вот примеры, показывающие, как правильно реализовать шаблон в wpf.
WPF Master Подробности MVVM Применение
Статья MSDN
пс:
не забудьте установить IsSynchronizedWithCurrentItem="true"