如何捕获嵌入ComboBox
的{{1}}触发的Selection Changed事件?我想为此使用MVVM模式,所以类似DataGridComboBoxColum
解决方案会很好。
XAML:
EventToCommmand
我想使用这样的东西但不知道在这种特殊情况下在何处/如何设置它。
<DataGridComboBoxColumn Header="ViewTemplate" Width="180" SelectedItemBinding="{Binding ViewTemplate}" DisplayMemberPath="Name">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
根据要求,这是我对XAML的完整代码:
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding SelectionChangedCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
并查看模型:
<UserControl x:Class="GrimshawRibbon.Revit.Views.ViewManager.ViewManagerView"
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="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:GrimshawRibbon.Revit.Views.ViewManager"
xmlns:ex="clr-namespace:GrimshawRibbon.Revit.Wpf.Extensions"
xmlns:controls="clr-namespace:MahApps.Metro.Controls;assembly=MahApps.Metro"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Platform"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="500">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Colors.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/Blue.xaml" />
<ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Accents/BaseLight.xaml" />
<ResourceDictionary Source="pack://application:,,,/GrimshawRibbon;component/Revit/Wpf/Style/GrimshawTheme.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid>
<ex:DataGridEx x:Name="dgViews"
Style="{StaticResource AzureDataGrid}"
Margin="10"
AutoGenerateColumns="False"
ItemsSource="{Binding Views, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
CanUserAddRows="False"
IsReadOnly="False"
SelectionMode="Extended"
SelectionUnit="FullRow"
SelectedItemsList="{Binding SelectedViews, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<i:Interaction.Triggers>
<i:EventTrigger EventName="CellEditEnding">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding CellEditEndingCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="*"/>
<DataGridTextColumn Header="ViewType" Binding="{Binding ViewType}" Width="100" IsReadOnly="True"/>
<DataGridTextColumn Header="ViewGroup" Binding="{Binding ViewGroup, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="130" IsReadOnly="False"/>
<DataGridTextColumn Header="ViewSubGroup" Binding="{Binding ViewSubGroup, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Width="130" IsReadOnly="False"/>
<DataGridCheckBoxColumn ElementStyle="{DynamicResource MetroDataGridCheckBox}"
EditingElementStyle="{DynamicResource MetroDataGridCheckBox}"
Header="OnSheet"
Binding="{Binding OnSheet, Mode=TwoWay}"
IsReadOnly="True"
Width="80">
</DataGridCheckBoxColumn>
<DataGridComboBoxColumn Header="ViewTemplate" Width="180" SelectedItemBinding="{Binding ViewTemplate}" DisplayMemberPath="Name">
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding DataContext.SelectChangeCommand, RelativeSource={RelativeSource AncestorType=UserControl}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
<Setter Property="IsReadOnly" Value="True"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="{x:Type ComboBox}" BasedOn="{StaticResource {x:Type ComboBox}}">
<Setter Property="ItemsSource" Value="{Binding DataContext.ViewTemplates, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
</DataGrid.Columns>
</ex:DataGridEx>
</Grid>
</UserControl>
答案 0 :(得分:2)
使用MVVM模式,您不会处理视图中SelectionChanged
元素的ComboBox
事件。
相反,您应该在ViewTemplate
属性的setter中或在您从那里调用的方法中实现选择更改的逻辑,只要在ComboBox
中选择了新项,就会设置该逻辑, .eg:
private ViewWrapper _viewTemplate;
public ViewWrapper ViewTemplate
{
get { return _viewTemplate; }
set { _viewTemplate = value; SelectionChanged(); }
}
这是MVVM的基石之一。只要视图设置了source属性,视图模型就可以执行某些逻辑。视图仅设置属性。它不处理任何事件。
修改:如果出于某种原因这不是一个选项,则应将DataGridComboBoxColumn
替换为DataGridTemplateColumn
,因为您无法将EventTrigger
应用于{ {1}}:
Style
答案 1 :(得分:0)
您可以将eventhandler添加到组合框中。我添加到grid的显示事件,当然可以添加另一个事件。
private void Grid1_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e)
{
ComboBox cb = e.Control as ComboBox;
if (cb!=null)
{ cb.SelectionChangeCommitted -= new EventHandler(cb_SelectedIndexChanged);
// now attach the event handler
cb.SelectionChangeCommitted += new EventHandler(cb_SelectedIndexChanged);
}
}}
答案 2 :(得分:0)
我会做的是这样的事情 所以在你的viewmodel中,你会有像
这样的东西Viewmodel.cs
public class ViewModel
{
public ViewModel()
{
_selectChangeCommand= new RelayCommand(OnSelectChange, CanSelectChange);
}
private RelayCommand _selectChangeCommand;
public ICommand SelectChangeCommand { get { return _selectChangeCommand; } }
private bool CanSelectChange()
{
return true;
}
private void OnSelectChange()
{
..//do something in here when you change something in your combo box
}
}
在您的MainWindow.xaml.cs中 做这样的事情:
this.DataContext = new ViewModel();
在ViewModel.xaml文件中
<ComboBox....>
<i:Interaction.Triggers>
<i:EventTrigger EventName="SelectionChanged">
<cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding SelectChangeCommand }"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</ComboBox>
一个重要的事情是确保viewmodel.xaml知道它引用的位置,以便它可以看到SelectionChangeCommand所在的位置,以便它可以进行绑定。仅供参考,对于relaycommand,我的建议是使用Galasoft.MVVMlight,这样你就不必自己实现relaycommand。