从代码中更改ListView的所选项目

时间:2014-09-10 20:06:15

标签: c# wpf listview

我正在使用WPF构建应用程序,而且我无法确定如何在ListView中显示通过代码选择的新选择。

我有一个包含大量项目的ListView。我想放一个按钮,将所选项目移动到视图中的下一个项目。要做到这一点,我必须能够取消选择一个项目,移动到下一个项目,然后选择它,以便选择实际显示给用户。

我的xaml代码如下:

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

我的申请代码如下:

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链接到我的数据以便正确更新?

编辑:根据Wyatt Earp的要求添加了MainWindow代码。

1 个答案:

答案 0 :(得分:1)

他们的意思是你需要在所有ViewModel中绑定一个对象,如此

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

enter image description here