繁体   English   中英

WPF 列表框选择已更改 MVVM

[英]WPF Listbox selectionchanged MVVM

我的 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 下面的块包含我的大部分应用程序的样式,但这只是一个片段。

在 XAML 中我的数据网格下方添加了代码行 - 用于测试目的的主代码。

<ListBox ItemsSource="{Binding SelectedItem.DuplicateSecurities, ElementName=dataGridOrders}" 
 SelectedItem="{Binding SelectedItem.Security, ElementName=dataGridOrders}"/>

我的数据网格加载正常。 当我单击一行时,该行会展开以显示证券列表。 我遇到的问题是,当我单击某个项目时,在此列表框中没有任何反应。 但是,我出于测试目的添加到数据网格下方的列表框确实有效。 例如,我单击其中一个项目,我的行被更新,我的行详细信息中的列表框也被选中。 很奇怪为什么我的 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>

应用程序 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 Class

 public class OrderBlocks : INotifyPropertyChanged
{
 private List<Order> _orders;
    [XmlElement("tF_Transactions")]
    public List<Order> Orders { get { return _orders; } set { _orders = value; OnPropertyChanged("Orders"); } }
}

订单Class

    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"); }
        }

保安 Class

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

将ListBox SelectionChanged事件绑定到ViewModel中的命令示例

<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框架。

希望这可以帮助

SelectionChanged与MVVM一起使用非常简单:

一种方法可以是绑定到ListBoxSelectedIndex属性,并在VM中的属性设置器中,相应地执行操作,因为只要属性更改它就会被触发。

示例: 这里

在此示例中,只要所选索引发生更改,该项的值就会增加1。

主要是:

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);
  }
}

xaml只会是:

<ListBox ItemsSource="{Binding Items}" SelectedIndex="{Binding SelectedIndex}" />

Items是我们绑定的项目的集合。

System.Windows.Interactivity.WPF package 已弃用。

安装Microsoft.Xaml.Behaviors.Wpf package

<ListBox ItemsSource="{Binding ListItems}" DisplayMemberPath="Name" SelectedItem="{Binding SelectedItem}">
     <Behaviors:Interaction.Triggers>
          <Behaviors:EventTrigger EventName="SelectionChanged">
               <Behaviors:InvokeCommandAction Command="{Binding ItemChangedCommand}" />
          </Behaviors:EventTrigger>
     </Behaviors:Interaction.Triggers>
</ListBox>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM