WPF列表框的SelectionChanged MVVM [英] WPF Listbox selectionchanged MVVM

查看:1127
本文介绍了WPF列表框的SelectionChanged MVVM的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在我的WPF应用程序列表框。我知道如何使用SelectionChanged事件。不过我想跟随MVVM设计。但是我不知道如何做到这一点。



我已经这样做了一个按钮,但不知道如果我可以做同样的事情?



 <按钮Grid.Column =0NA​​ME =buttImportCONTENT =导入文件命令={结合CommandButtImport}风格={静态资源ButtonTemplate}/> 



&NBSP;

 公共类视图模型:INotifyPropertyChanged的
{
//为进口订单文件
公众的ICommand CommandButtImport {拿到按钮;组; }

公共视图模型()
{
CommandButtImport =新MyCommands(
ExecuteCommandButtImport,
CanExecuteCommandButtImport);
}

私人布尔CanExecuteCommandButtImport(对象参数)
{
返回真;
}

//导入按钮
私人无效ExecuteCommandButtImport(对象参数)
{
//一些代码
}
}

以上修改请忽略代码



我已经改变了我的代码,以便有以下转贴什么我现在有。我有一个奇怪的问题。该XAML - 主代码包含了我的DataGrid的代码。以下应用程序块 - XAML包含了我的大多数应用程序的造型,但仅仅是一个snipet



同时



< 。p>代码行加入我的XAML的DataGrid下 - 主代码用于测试目的

 < ListBox中的ItemsSource ={绑定的SelectedItem .DuplicateSecurities,的ElementName = dataGridOrders}的SelectedItem ={结合SelectedItem.Security,的ElementName = dataGridOrders}/> 



我的DataGrid中加载罚款。当我点击某一行上,该行展开以显示证券名单。我的问题是,在这个列表框中当我点击一个项目没有任何反应。不过,我将我的数据网格下面,用于测试目的列表框不工作。比如我点击的项目之一,我行被更新,也是我行的详细列表框中被选中。它很奇怪,为什么在我的rowdetail列表框中不工作,但我的DataGrid下的人做。 ?任何想法



XAML - 主代码



 < StackPanel的> 
<! - 数据网格显示订单 - >
< DataGrid中的DataContext ={结合OrderBlock}
X:NAME =dataGridOrders
的ItemsSource ={约束力的命令}
风格={StaticResource的DataGridTemplate}
ColumnHeaderStyle ={StaticResource的DG_ColumnHeader}
RowHeaderStyle ={StaticResource的DG_RowHeader}
RowStyle ={StaticResource的DG_Row}
CellStyle ={StaticResource的DG_Cell}
RowDetailsTemplate ={StaticResource的DG_RowDetail}
的AutoGenerateColumns =FALSE
的Horizo​​ntalAlignment =拉伸
VerticalAlignment =拉伸
背景=银
RowHeaderWidth =30
保证金=25,5,20,15>

< DataGrid.Columns>
< DataGridComboBoxColumn标题=行动>
< DataGridComboBoxColumn.ElementStyle>
<风格的TargetType =组合框>
< setter属性=的ItemsSourceVALUE ={绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型的DataGrid}},路径= DataContext.StatusList}/>
< setter属性=IsReadOnlyVALUE =真/>
< setter属性=的SelectedValueVALUE ={结合StatusGood}/>
< /样式和GT;
< /DataGridComboBoxColumn.ElementStyle>
< DataGridComboBoxColumn.EditingElementStyle>
<风格的TargetType =组合框>
< setter属性=的ItemsSourceVALUE ={绑定的RelativeSource = {的RelativeSource FindAncestor,AncestorType = {X:类型的DataGrid}},路径= DataContext.StatusList}/>
< setter属性=IsReadOnlyVALUE =真/>
< setter属性=的SelectedValueVALUE ={结合StatusGood}/>
< /样式和GT;
< /DataGridComboBoxColumn.EditingElementStyle>
< / DataGridComboBoxColumn>
< DataGridTextColumn标题=基金绑定={绑定账户}IsReadOnly =真/>
< DataGridTextColumn标题=安全ID绑定={结合Security.ID}IsReadOnly =真/>
< DataGridTextColumn标题=ThinkFolio安全ID绑定={结合ThinkFolioSecurityID}IsReadOnly =真/>
< DataGridTextColumn标题=安全名称绑定={结合Security.Name}IsReadOnly =真/>
< DataGridTextColumn标题=买/卖绑定={结合TransType}IsReadOnly =真/>
< DataGridTextColumn标题=数量绑定={结合OrderQunatity,的StringFormat = \ {0:N0\}}IsReadOnly =FALSE/>
< DataGridTextColumn标题=货币绑定={结合BuyCurrency}IsReadOnly =FALSE/>
< DataGridTextColumn标题=经理绑定={结合FundManager}IsReadOnly =真/>
< DataGridTextColumn标题=订单原因绑定={结合OrderReason}IsReadOnly =真/>
< DataGridTextColumn标题=拒绝原因绑定={结合RejectReason}IsReadOnly =真WIDTH =*/>
< /DataGrid.Columns>
< / DataGrid的>
< ListBox中的ItemsSource ={结合SelectedItem.DuplicateSecurities,的ElementName = dataGridOrders}的SelectedItem ={结合SelectedItem.Security,的ElementName = dataGridOrders}/>
< / StackPanel的>

应用XAML

 <! - 行详细信息模板的数据网格 - > 
<的DataTemplate X:键=DG_RowDetail>
<电网X:NAME =RowDetailGrid
保证金=5
的Horizo​​ntalAlignment =左>
< BORDER的Horizo​​ntalAlignment =左
VerticalAlignment =评出的
WIDTH =500
高度=80
CornerRadius =5>
< Border.Background>
<一个LinearGradientBrush StartPoint可以=0,0终点=0.1>
将;渐变停止偏移=0颜色=透明/>
将;渐变停止偏移=1颜色=透明/>
< /一个LinearGradientBrush>
< /Border.Background>
<网格和GT;
< Grid.RowDefinitions>
< RowDefinition高度=*/>
< RowDefinition HEIGHT =2.5 */>
< /Grid.RowDefinitions>
< Grid.ColumnDefinitions>
< ColumnDefinition WIDTH =*/>
< /Grid.ColumnDefinitions>
< TextBlock的Grid.Row =0
Grid.ColumnSpan =3
保证金=5,0,0,5
的Horizo​​ntalAlignment =左
字号=12
粗细=大胆
前景=黑
文本=选择安全标识符>
< / TextBlock的>
<列表框Grid.Row =1Grid.ColumnSpan =3NAME =lbIdentifier的ItemsSource ={结合DuplicateSecurities}的SelectedItem ={绑定安全}
的SelectionMode =单Horizo​​ntalContentAlignment =拉伸>
< ListBox.ItemTemplate>
<&DataTemplate的GT;
<电网保证金=0.2>
< Grid.ColumnDefinitions>
< ColumnDefinition />
< ColumnDefinition WIDTH =*/>
< /Grid.ColumnDefinitions>
< TextBlock的Grid.Column =0文本={绑定路径= ID}字号=10的Horizo​​ntalAlignment =左保证金=5,0,0,0/>
< TextBlock的Grid.Column =1文本={绑定路径=名称}字号=10的Horizo​​ntalAlignment =左保证金=5,0,0,0/>
< /网格和GT;
< / DataTemplate中>
< /ListBox.ItemTemplate>
< /列表框>
< /网格和GT;
< /边框>
< /网格和GT;
< / DataTemplate中>



视图模型

 公共类视图模型:INotifyPropertyChanged的
{
公众的ICommand CommandButtImport {搞定;组; } //为进口订单文件
公共ICommand的CommandButtSend按钮{搞定;组; } //在用户发送订单中的数据网格thinkFolio
公开的ICommand CommandButtExit {获取按钮;组; } //出境申请

私人QoEMain _QoEManager; //管理模式
公共QoEMain QoEManager {{返回this._QoEManager; }集合{_QoEManager =价值; }}

私人OrderBlocks _orderBlock; //为了块 - 包含了所有的订单信息
公共OrderBlocks OrderBlock
{
得到
{
返回this._orderBlock;
}

{
this._orderBlock =价值;
OnPropertyChanged(OrderBlock);
}
}
}



OrderBlocks类,它包含的其他班

 公共类OrderBlocks:INotifyPropertyChanged的
{
私有列表<排序> _命令;
[的XmlElement(tF_Transactions)]
公开名单<排序>订单{{返回_orders; }集合{_orders =价值; OnPropertyChanged(订单); }}
}



订单班

 公共类订单:INotifyPropertyChanged的
{
保障安全;
公安部安全防范
{
{返回安全; }
集合{安全=价值; OnPropertyChanged(安全); }
}

名单,LT;安全> duplicateSecurities;
公开名单<安全> DuplicateSecurities
{
{返回duplicateSecurities; }
集合{duplicateSecurities =价值; OnPropertyChanged(DuplicateSecurities); }
}



安全类

 公共类安全:INotifyPropertyChanged的
{
私人字符串_id;
公共字符串ID
{
得到
{
返回_id;
}

{
_id =价值;
OnPropertyChanged(ID);
}
}

私人字符串_name;
公共字符串名称
{
得到
{
返回_name;
}

{
_name =价值;
OnPropertyChanged(姓名);
}
}

公众安全(){}

公众安全(字符串NEWID,串了newName)
{
ID = NEWID;
名称=了newName;
}

修改 - 我的代码现在工作,请参见下面的代码片段对我的作品

 <数据网格Grid.Row =1Grid.Column =0
的ItemsSource ={结合SelectedItem.DuplicateSecurities,
的ElementName = dataGridOrders}
的SelectedItem ={结合SelectedItem.Security,的ElementName = dataGridOrders}


解决方案

使用的SelectionChanged 很简单:



这是方法可以绑定到 ListBox的的SelectedIndex 属性并在虚拟机属性setter,采取相应的行动,因为这将被触发每当属性发生变化



例如:的在这里



在这个例子中,只要所选择的指数的变化,该项目的值增加。一个



主要位为:

 公众诠释的SelectedIndex {
获得{
返回_selectedIndex;
}

集合{
如果(_selectedIndex ==值){
的回报;
}

//此时_selectedIndex是老选定项目的索引

_selectedIndex =价值;

//此时_selectedIndex是新选择的项目的索引

RaisePropertyChanged(()=>的SelectedIndex);
}
}



XAML也只是:

 < ListBox中的ItemsSource ={绑定表项}的SelectedIndex ={结合的SelectedIndex}/> 



产品是我们结合项目的集合到


I have a list box in my WPF application. I know how to use the selectionchanged event. However I am trying to follow the MVVM design. However I am not sure how to do this.

I have done this for a button however not sure if I can do the same thing?

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

EDIT Please ignore code above

I have changed my code so have reposted below what I currently have. I have a strange issue. The XAML - Main Code contains the code for my datagrid. The block below App - XAML contains the styling for most of my app, but is just a snipet.

Also

Code Line added beneath my datagrid in XAML - Main Code for testing purposes.

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

My datagrid loads fine. When I click on a row, the row expands to show a list of Securities. The issue I have is that in this listbox when I click on an item nothing happens. However the Listbox which I added beneath my datagrid for testing purposes does work. For example I click on one of the items and my row is updated, also the listbox in my row detail becomes selected. Its very strange why the listbox in my rowdetail doesn't work but the one beneath my datagrid does. Any ideas?

XAML - Main Code

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

ViewModel

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 which contains the other classes

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

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

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

Edit - My code now works please see the code snippet below that works for me

<DataGrid Grid.Row="1" Grid.Column="0" 
     ItemsSource="{Binding SelectedItem.DuplicateSecurities, 
            ElementName=dataGridOrders}" 
     SelectedItem="{Binding SelectedItem.Security, ElementName=dataGridOrders}" 

解决方案

using SelectionChanged with MVVM is quite simple:

An approach could be to bind to the SelectedIndex property of the ListBox and in the property setter in the VM, act accordingly as it would be triggered whenever the property changes.

Example: Here

In this example whenever the selected index changes, the value of that item is increased by one.

the main bit is:

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 would just be:

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

Items is the collection of items we bind to.

这篇关于WPF列表框的SelectionChanged MVVM的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆