我的WPF应用程序中有一个列表框。我知道如何使用selectionchanged事件。但是我试图遵循MVVM设计。但是我不知道该怎么做。
我已经为按钮做了这个,但不确定我是否可以做同样的事情?
<Button Grid.Column="0" Name="buttImport"
Content="Import File"
Command="{Binding CommandButtImport}"
Style="{StaticResource ButtonTemplate}"/>
public class ViewModel : INotifyPropertyChanged
{
// for the button that imports the orders file
public ICommand CommandButtImport { get; set; }
public ViewModel()
{
CommandButtImport = new MyCommands(
ExecuteCommandButtImport,
CanExecuteCommandButtImport);
}
private bool CanExecuteCommandButtImport(object parameter)
{
return true;
}
// import button
private void ExecuteCommandButtImport(object parameter)
{
// some code
}
}
编辑请忽略上面的代码
我已经更改了我的代码,所以转发到了我目前的代码之下。我有一个奇怪的问题。 XAML - 主代码包含我的数据网格的代码。 App - XAML下面的块包含我的大多数应用程序的样式,但只是一个snipet。
另外
在XAML中的数据网格下添加了代码行 - 用于测试目的的主代码。
<ListBox ItemsSource="{Binding SelectedItem.DuplicateSecurities, ElementName=dataGridOrders}"
SelectedItem="{Binding SelectedItem.Security, ElementName=dataGridOrders}"/>
我的datagrid加载正常。当我点击一行时,该行会展开以显示证券列表。我遇到的问题是,当我点击一个项目时,在这个列表框中没有任何反应。但是我在数据网格下添加的Listbox用于测试目的确实有效。例如,我单击其中一个项目并更新我的行,同时我的行详细信息中的列表框也会被选中。很奇怪为什么我的rowdetail中的列表框不起作用,但是我的数据网格下面的列表框不起作用。有什么想法吗?
XAML - 主要代码
<StackPanel>
<!-- The data grid to display orders-->
<DataGrid DataContext="{Binding OrderBlock}"
x:Name="dataGridOrders"
ItemsSource="{Binding Orders}"
Style="{StaticResource DataGridTemplate}"
ColumnHeaderStyle="{StaticResource DG_ColumnHeader}"
RowHeaderStyle="{StaticResource DG_RowHeader}"
RowStyle="{StaticResource DG_Row}"
CellStyle="{StaticResource DG_Cell}"
RowDetailsTemplate="{StaticResource DG_RowDetail}"
AutoGenerateColumns="False"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="Silver"
RowHeaderWidth="30"
Margin="25,5,20,15">
<DataGrid.Columns>
<DataGridComboBoxColumn Header="Action">
<DataGridComboBoxColumn.ElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.StatusList}"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="SelectedValue" Value="{Binding StatusGood}"/>
</Style>
</DataGridComboBoxColumn.ElementStyle>
<DataGridComboBoxColumn.EditingElementStyle>
<Style TargetType="ComboBox">
<Setter Property="ItemsSource" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}, Path=DataContext.StatusList}"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="SelectedValue" Value="{Binding StatusGood}"/>
</Style>
</DataGridComboBoxColumn.EditingElementStyle>
</DataGridComboBoxColumn>
<DataGridTextColumn Header="Fund" Binding="{Binding Account}" IsReadOnly="True"/>
<DataGridTextColumn Header="Security ID" Binding="{Binding Security.ID}" IsReadOnly="True"/>
<DataGridTextColumn Header="ThinkFolio Security ID" Binding="{Binding ThinkFolioSecurityID}" IsReadOnly="True"/>
<DataGridTextColumn Header="Security Name" Binding="{Binding Security.Name}" IsReadOnly="True"/>
<DataGridTextColumn Header="Buy/Sell" Binding="{Binding TransType}" IsReadOnly="True"/>
<DataGridTextColumn Header="Quantity" Binding="{Binding OrderQunatity, StringFormat=\{0:N0\}}" IsReadOnly="False"/>
<DataGridTextColumn Header="Currency" Binding="{Binding BuyCurrency}" IsReadOnly="False"/>
<DataGridTextColumn Header="Manager" Binding="{Binding FundManager}" IsReadOnly="True"/>
<DataGridTextColumn Header="Order Reason" Binding="{Binding OrderReason}" IsReadOnly="True"/>
<DataGridTextColumn Header="Reject Reason" Binding="{Binding RejectReason}" IsReadOnly="True" Width="*"/>
</DataGrid.Columns>
</DataGrid>
<ListBox ItemsSource="{Binding SelectedItem.DuplicateSecurities, ElementName=dataGridOrders}" SelectedItem="{Binding SelectedItem.Security, ElementName=dataGridOrders}"/>
</StackPanel>
App XAML
<!-- Row Detail Template for Data Grid -->
<DataTemplate x:Key="DG_RowDetail">
<Grid x:Name="RowDetailGrid"
Margin="5"
HorizontalAlignment="Left">
<Border HorizontalAlignment="Left"
VerticalAlignment="Top"
Width="500"
Height="80"
CornerRadius="5">
<Border.Background>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Offset="0" Color="Transparent"/>
<GradientStop Offset="1" Color="Transparent"/>
</LinearGradientBrush>
</Border.Background>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="2.5*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0"
Grid.ColumnSpan="3"
Margin="5,0,0,5"
HorizontalAlignment="Left"
FontSize="12"
FontWeight="Bold"
Foreground="Black"
Text="Select Security Identifier">
</TextBlock>
<ListBox Grid.Row="1" Grid.ColumnSpan="3" Name="lbIdentifier" ItemsSource="{Binding DuplicateSecurities}" SelectedItem="{Binding Security}"
SelectionMode="Single" HorizontalContentAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<Grid Margin="0,2">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=ID}" FontSize="10" HorizontalAlignment="Left" Margin="5,0,0,0"/>
<TextBlock Grid.Column="1" Text="{Binding Path=Name}" FontSize="10" HorizontalAlignment="Left" Margin="5,0,0,0"/>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
</Border>
</Grid>
</DataTemplate>
视图模型
public class ViewModel : INotifyPropertyChanged
{
public ICommand CommandButtImport { get; set; } // for the button that imports the orders file
public ICommand CommandButtSend { get; set; } // the button where the user sends the orders in our data grid to thinkFolio
public ICommand CommandButtExit { get; set; } // exit application
private QoEMain _QoEManager; // manages the Model
public QoEMain QoEManager { get { return this._QoEManager; } set { _QoEManager = value; } }
private OrderBlocks _orderBlock; // order block - contains all the order information
public OrderBlocks OrderBlock
{
get
{
return this._orderBlock;
}
set
{
this._orderBlock = value;
OnPropertyChanged("OrderBlock");
}
}
}
包含其他类的OrderBlocks类
public class OrderBlocks : INotifyPropertyChanged
{
private List<Order> _orders;
[XmlElement("tF_Transactions")]
public List<Order> Orders { get { return _orders; } set { _orders = value; OnPropertyChanged("Orders"); } }
}
订单类
public class Order : INotifyPropertyChanged
{
Security security;
public Security Security
{
get { return security; }
set { security = value; OnPropertyChanged("Security"); }
}
List<Security> duplicateSecurities;
public List<Security> DuplicateSecurities
{
get { return duplicateSecurities; }
set { duplicateSecurities = value; OnPropertyChanged("DuplicateSecurities"); }
}
安全等级
public class Security : INotifyPropertyChanged
{
private string _id;
public string ID
{
get
{
return _id;
}
set
{
_id = value;
OnPropertyChanged("ID");
}
}
private string _name;
public string Name
{
get
{
return _name;
}
set
{
_name = value;
OnPropertyChanged("Name");
}
}
public Security() { }
public Security(string newID, string newName)
{
ID = newID;
Name = newName;
}
修改 - 我的代码现已有效,请参阅下面适合我的代码段
<DataGrid Grid.Row="1" Grid.Column="0"
ItemsSource="{Binding SelectedItem.DuplicateSecurities, ElementName=dataGridOrders}"
SelectedItem="{Binding SelectedItem.Security, ElementName=dataGridOrders}">
答案 0 :(得分:38)
在ViewModel
中绑定ListBoxSelectionChanged
事件的示例
<ListBox x:Name="myListBox" ItemsSource="{Binding SomeCollection}">
<ie:Interaction.Triggers>
<ie:EventTrigger EventName="SelectionChanged">
<ie:InvokeCommandAction Command="{Binding SelectedItemChangedCommand}" CommandParameter="{Binding ElementName=myListBox, Path=SelectedItem}"/>
</ie:EventTrigger>
</ie:Interaction.Triggers>
</ListBox >
在ViewModel
:
public class myViewModel
{
public myViewModel()
{
SelectedItemChangedCommand = new DelegateCommand<object>((selectedItem) =>
{
// Logic goes here
});
}
public List<SomeData> SomeCollection { get; set; }
public DelegateCommand<object> SelectedItemChangedCommand { get; set; }
}
此特定示例使用Prism MVVM Framework,但您可以将任何其他MVVM框架应用于相同的想法。
希望这有帮助
答案 1 :(得分:22)
将SelectionChanged
与MVVM结合使用非常简单:
一种方法可能是绑定到SelectedIndex
的{{1}}属性,并在VM中的属性设置器中,相应地采取行动,因为只要属性发生变化就会触发它。
示例:Here
在此示例中,只要所选索引发生更改,该项的值就会增加一个。
主要是:
ListBox
xaml就是:
public int SelectedIndex {
get {
return _selectedIndex;
}
set {
if (_selectedIndex == value) {
return;
}
// At this point _selectedIndex is the old selected item's index
_selectedIndex = value;
// At this point _selectedIndex is the new selected item's index
RaisePropertyChanged(() => SelectedIndex);
}
}
<ListBox ItemsSource="{Binding Items}" SelectedIndex="{Binding SelectedIndex}" />
是我们绑定的项目集合。