2014-09-10 108 views
1

我正在构建一个使用WPF的应用程序,并且在解决如何在通过代码选择的ListView中显示新选择时遇到问题。更改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所要求的主窗口代码。

+0

^h ow来了'_IsChecked'被声明为私有,但是'_IsSelected'被宣布为公共是否存在访问级别差异的原因..并不重要,但是这是什么在我身上发现了最多 – MethodMan 2014-09-10 20:11:52

+0

其中是这个属性绑定有一个为isChecked '' – MethodMan 2014-09-10 20:13:33

+1

它看起来像我的ListView的'SelectedItem'绑定到'IsSelected'属性。我怀疑这不是你想要的。此外,该片段缺少设置ItemsSource的位置。这是发生在你的代码隐藏吗?基本上,你希望你的ItemsSource绑定到一些'ObservableCollection ',然后,'SelectedItem'应该绑定到同一个ViewModel上的'DataObject'。 – 2014-09-10 20:14:50

回答

1

他们的意思是你需要绑定一个对象在对所有视图模型,像这样

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

+0

啊,谢谢。所以看起来像我在我的代码中缺少viewmodel,如上所示。我想知道,如果我不能实现那么一个。 – 2014-09-11 15:43:50

+0

Np,请记住标记为解决方案,如果它确实设法解决您的问题:) – 2014-09-11 15:53:22