我正在使用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代码。
答案 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();
}
}