从代码更改ListView的选定项目 [英] Changing ListView's selected item from code

查看:44
本文介绍了从代码更改ListView的选定项目的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用WPF构造一个应用程序,但在弄清楚如何在通过代码选择的ListView中显示新选择时遇到了麻烦.

I'm constructing an application using WPF and I'm having trouble with figuring out how to display a new selection in the ListView that's selected via code.

我有一个带有一堆物品的ListView.我想放置一个按钮,将选定的项目移动到视图中的下一个项目.为此,我必须能够取消选择一个项目,移至下一个项目,然后再选择它,以使选择实际上显示给用户.

I have a ListView with a bunch of items. I want to put a button that moves the selected item to the next item in the view. To do this I have to be able to deselect an item, move to the next item, and then select it so that the selection actually appears to the user.

我的xaml代码如下:

My xaml code is as follows:

    <Border Grid.Row="1" CornerRadius="10" BorderBrush="Black" BorderThickness="10">
      <ListView x:Name="lvLogPackets" Background="#FF0C3A58" Foreground="White" SelectionChanged="lvLogPackets_SelectionChanged" SelectedItem="{Binding Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, Path=IsSelected}">
        <ListView.ContextMenu>
          <ContextMenu Name="lvCMenu" Opened="menuOpened_click">
            <MenuItem Header="Filter Checked" IsCheckable="True" Checked="menuViewCheckbox_Checked" Unchecked="menuViewCheckbox_Unchecked"/>
            <MenuItem Header="Filter Selected" IsCheckable="True" Checked="menuViewSelected_Checked" Unchecked="menuViewSelected_Unchecked"/>
            <Separator />
            <MenuItem Header="Δt: N/A"/>
            <Separator />
            <MenuItem Header="Pop Out Data" Click="menuPopOut"/>
            <Separator />
            <MenuItem Header="Copy Payload CSV" Click="menuCopyPayloadCsv"/>
          </ContextMenu>
        </ListView.ContextMenu>
        <ListView.ItemContainerStyle>
          <Style TargetType="ListViewItem">
            <Style.Triggers>
              <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="Green"/>
              </Trigger>
              <Trigger Property="IsMouseOver" Value="True">
                <Setter Property="Background" Value="Red"/>
              </Trigger>
            </Style.Triggers>
          </Style>
        </ListView.ItemContainerStyle>
        <ListView.View>
          <GridView x:Name="lvGridView">
            <GridViewColumn Width="30">
              <GridViewColumn.CellTemplate>
                <DataTemplate>
                  <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />                      
                </DataTemplate>
              </GridViewColumn.CellTemplate>
            </GridViewColumn>
            <GridViewColumn Header="Index" Width="100" DisplayMemberBinding="{Binding Path=Index}"/>
            <GridViewColumn Header="SysTime" Width="100" DisplayMemberBinding="{Binding Path=SysTime}"/>
            <GridViewColumn Header="ElapsedTime" Width="150" DisplayMemberBinding="{Binding Path=ElapsedTime}"/>
            <GridViewColumn Header="Source" Width="100" DisplayMemberBinding="{Binding Path=Source}"/>
            <GridViewColumn Header="Destination" Width="100" DisplayMemberBinding="{Binding Path=Destination}"/>
            <GridViewColumn Header="CmdID" Width="100" DisplayMemberBinding="{Binding Path=CmdID}"/>
            <GridViewColumn Header="PayloadSize" Width="100" DisplayMemberBinding="{Binding Path=PayloadSize}"/>
            <GridViewColumn Header="Payload" Width="800" DisplayMemberBinding="{Binding Path=Payload}"/>
          </GridView>
        </ListView.View>
      </ListView>
    </Border>

我的应用程序代码如下:

My application code is as follows:

public class LogItem : INotifyPropertyChanged
{
  public string Index { get; set; }
  public string SysTime { get; set; }
  public string ElapsedTime { get; set; }
  public string Source { get; set; }
  public string Destination { get; set; }
  public string CmdID { get; set; }
  public string PayloadSize { get; set; }
  public string Payload { get; set; }

  public bool _IsSelected;
  public bool IsSelected
  {
    get { return _IsSelected; }
    set { _IsSelected = value; NotifyPropertyChanged("IsSelected"); }
  }

  private bool _IsChecked;
  public bool IsChecked 
  {
    get { return _IsChecked; }
    set { _IsChecked = value; NotifyPropertyChanged("IsChecked"); }
  }

  ...

  public event PropertyChangedEventHandler PropertyChanged;
  protected void NotifyPropertyChanged(string strPropertyName)
  {
    if (PropertyChanged != null)
      PropertyChanged(this, new PropertyChangedEventArgs(strPropertyName));
  }
}

public partial class MainWindow : RibbonWindow
{
  private ObservableCollection<LogItem> m_LogItems = new ObservableCollection<LogItem>();
  private void RibbonWindow_Loaded(object sender, RoutedEventArgs e)
  {
    lvLogPackets.ItemsSource = m_LogItems;
  }
}

我所有其他绑定似乎都可以正常工作,包括IsChecked绑定.我在这里想念什么?如何正确地将SelectedItem/s链接到我的数据,以便其正确更新?

All my other bindings appear to work correctly, including the IsChecked binding. What am I missing here? How do I properly link SelectedItem/s to my data so that it updates correctly?

根据Wyatt Earp的要求添加了MainWindow代码.

Added MainWindow code as requested by Wyatt Earp.

推荐答案

它们意味着您需要像这样在整个ViewModel中将其绑定一个对象

They mean you need to Bind it an object in the over all ViewModel like so

public class sample_model
{
    public sample_model(string artist, string song, string extra = "")
    {
        this.Artist = artist;
        this.Song = song;
        this.Extra = extra;
    }

    public string Artist { get; set; }
    public string Song { get; set; }
    public string Extra { get; set; }
}

public class sample_viewmodel  : INotifyPropertyChanged 
{
    public sample_viewmodel()
    {
        this.DataSource = CreateData();

    }

    // implement the INotify
    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (null != handler)
        {
            handler(this, new PropertyChangedEventArgs(propertyName));
        }
    }

    // create a static list for our demo
    private ObservableCollection<sample_model> CreateData()
    {
        ObservableCollection<sample_model> my_list = new ObservableCollection<sample_model>();
        my_list.Add(new sample_model("Faith + 1", "Body of Christ", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ Again", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "A Night With the Lord", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Touch Me Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Found Jesus (With Someone Else)", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Savior Self", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Christ What a Day", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Three Times My Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus Touched Me", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Lord is my Savior", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "I Wasn't Born Again Yesterday", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Pleasing Jesus", "A Track"));
        my_list.Add(new sample_model("Faith + 1", "Jesus (Looks Kinda Hot)", "A Track"));
        my_list.Add(new sample_model("Butters", "What What", "B Track"));
        return my_list;
    }

    public ObservableCollection<sample_model> DataSource { get; set; }

    sample_model _seletedItem;
    public sample_model SelectedItem
    {
        get { return _seletedItem; }
        set
        {
            _seletedItem = value;
            NotifyPropertyChanged("SelectedItem");
        }
    }

}


<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="217*"/>
        <ColumnDefinition Width="300*"/>
    </Grid.ColumnDefinitions>
    <ListView x:Name="myListView" Width="200" SelectionChanged="myListView_SelectionChanged" HorizontalAlignment="Left"
              SelectedItem="{Binding SelectedItem, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
        <ListView.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Artist}"></TextBlock>
                    <TextBlock Text="{Binding Song}"></TextBlock>
                </StackPanel>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
    <Button x:Name="myButton" Grid.Column="1" Content="Change Selected Item" Click="myButton_Click"></Button>
</Grid>


public partial class MainWindow : Window
{
    private sample_viewmodel viewmodel;
    public MainWindow()
    {
        InitializeComponent();
    }

    private void Window_Loaded(object sender, RoutedEventArgs e)
    {
        sample_viewmodel viewmodel = new sample_viewmodel();  // create the view model
        myListView.DataContext = viewmodel;                   // set the datacontext (this will link the commands)
        myListView.ItemsSource = viewmodel.DataSource;        // set the ItemsSource, this will link the Artist,Songs
    }

    private void myListView_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
    }

    private void myButton_Click(object sender, RoutedEventArgs e)
    {
        // only for testing purpose, don't actually use this code
        myListView.SelectedItem = (sample_model) ((ObservableCollection<sample_model>)myListView.ItemsSource)[2];

        // or you can do this
        // viewmodel.SelectedItem = (sample_model)((ObservableCollection<sample_model>)myListView.ItemsSource)[2];

        // or this
        // viewmodel.SelectedItem = viewmodel.DataSource[2];

        myListView.Focus();            
    }
}


这篇关于从代码更改ListView的选定项目的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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