2011-04-06 123 views
0

让我再试一次......这里是XAML。您可以看到CollectionViewSource,将它用作DataContext的Grid,ListView和Delete按钮。发生什么事情是,当我点击ListView中的一行(并且样式触发器激发选择ListViewItem)时,该行被选中。当我点击删除按钮时,onclick会触发,但CurrentPosition属性设置为-1。什么是阻止CurrentPosition属性被更新。CurrentPosition属性没有正确更新

XAML

<Window x:Class="PretzelsUI.Admin.Ovens" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="" 
    Height="344" 
    Width="474" 
    mc:Ignorable="d" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:my="clr-namespace:Pretzels.Model;assembly=Pretzels.Model" 
    ResizeMode="NoResize" 
    WindowStartupLocation="CenterOwner" 
    Background="{StaticResource WindowGradient}"  
    Loaded="Window_Loaded"> 
<Window.Resources> 
    <CollectionViewSource x:Key="ovenViewSource" d:DesignSource="{d:DesignInstance my:Oven, CreateList=True}" /> 
</Window.Resources> 
<Grid DataContext="{StaticResource ovenViewSource}"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="Auto" /> 
    </Grid.RowDefinitions> 
    <Border Grid.Row="0" BorderBrush="{StaticResource formTitleBorderBrush}" BorderThickness="2" Name="border1" CornerRadius="30" Padding="7" Background="{StaticResource formTitleBackgroundBrush}" VerticalAlignment="Center" Margin="11"> 
     <TextBlock Name="textBlock1" Text="Ovens" FontSize="18" FontWeight="Bold" Foreground="{StaticResource formTitleForegroundBrush}" /> 
    </Border> 
    <ListView IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding}" Name="ovenListView" SelectionMode="Single" Height="177" Grid.Row="1" TabIndex="2" Margin="5,5,5,0"> 
     <ListView.ItemContainerStyle> 
      <Style TargetType="ListViewItem"> 
       <Setter Property="Control.HorizontalContentAlignment" Value="Stretch" /> 
       <Setter Property="Control.VerticalContentAlignment" Value="Stretch" /> 
       <!--<Style.Triggers> 
        <Trigger Property="IsKeyboardFocusWithin" Value="True"> 
         <Setter Property="IsSelected" Value="True" /> 
        </Trigger> 
       </Style.Triggers>--> 
      </Style> 
     </ListView.ItemContainerStyle> 
     <ListView.View> 
      <GridView>      
       <GridViewColumn x:Name="nameColumn" Header="Name" Width="100"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <TextBox Margin="-6,-1" Text="{Binding Path=OvenName, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true, UpdateSourceTrigger=PropertyChanged}" Width="Auto" /> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
       <GridViewColumn x:Name="descriptionColumn" Header="Description" Width="300"> 
        <GridViewColumn.CellTemplate> 
         <DataTemplate> 
          <TextBox Margin="-6,-1" Text="{Binding Path=OvenDescription, Mode=TwoWay, ValidatesOnExceptions=true, NotifyOnValidationError=true}" Width="Auto" MaxLength="100"/> 
         </DataTemplate> 
        </GridViewColumn.CellTemplate> 
       </GridViewColumn> 
      </GridView> 
     </ListView.View> 
    </ListView> 
    <StackPanel Grid.Row="2" Name="stackPanel2" Margin="0,30,0,0" Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> 
     <Button Content="New" Height="23" Margin="2,0,2,0" TabIndex="3" Name="btnAdd" Width="75" Click="btnInsrt_Click" /> 
     <Button Content="Save" Height="23" Margin="2,0,2,0" TabIndex="4" Name="btnSave" Width="75" Click="btnSave_Click" /> 
     <Button Content="Delete" Height="23" Margin="2,0,2,0" TabIndex="5" Name="btndelete" Width="75" Click="btndelete_Click" /> 
    </StackPanel> 
</Grid> 

C#

public partial class Ovens : Window 
{ 
    private PretzelEntities dbcontext = new PretzelEntities(); 
    //private OvenCollection EntityData; 
    private CollectionViewSource ViewSource; 
    private BindingListCollectionView OvenView; 

    public Ovens() 
    { 
     InitializeComponent(); 
    } 

    private void Window_Loaded(object sender, RoutedEventArgs e) 
    { 
     ViewSource = (CollectionViewSource)this.FindResource("ovenViewSource"); 

     ViewSource.Source = from s in dbcontext.Ovens select s; 
     OvenView = (BindingListCollectionView)(ViewSource.View); 
    } 


    private void btndelete_Click(object sender, RoutedEventArgs e) 
    { 
      if (OvenView.CurrentPosition > -1) 
      { 
       if (MessageBox.Show("Do you really want to delete this Oven?", "Delete Confirmation", MessageBoxButton.YesNo) == MessageBoxResult.Yes) 
       { 
        this.OvenView.RemoveAt(this.OvenView.CurrentPosition); 
       } 
      } 
      else 
      { 
       MessageBox.Show("Nothing to Delete.", "Error", MessageBoxButton.OK); 
      } 
    } 




enter code here 

我认为正在发生的事情是,当触发器在的ListCollectionView的CURRENTITEM/CurrentPosition没有被正确地更新。我不知道要做什么(尽管我知道可用的方法),当我点击其中一行的文本框时手动执行此操作。不知道该怎么做,所以我可能只需使用VisualTreeHelper手动定位选定的ListViewItem。

+0

你确定ListView绑定到*相同*集合视图吗?我们无法从您发布的代码中判断出来。 – 2011-04-06 17:25:55

+0

同意,这里有很多东西可能是错的。我现在还没有看到这个代码可能会连接到正确的源代码。 – poindexter12 2011-04-06 17:35:41

+0

我相信如此。该页面在Windows.Resources(ovenViewSource)中具有CollectionViewSource上面显示的ListView位于Grid内()。让我知道如果我还没有给出所有的信息 – MikeC 2011-04-06 17:36:11

回答

0

我终于放弃了风格触发器,只是处理了ListView行内textbox/combobox的GotFocus事件。在处理程序中,我能够获得ListViewItem并将IsSelected设置为true。像冠军一样工作。

private void TextBox_GotFocus(object sender, RoutedEventArgs e) 
    { 
     Control ctrl = sender as Control; 
     ContentPresenter cp = (ContentPresenter)ctrl.TemplatedParent; 
     GridViewRowPresenter gp = (GridViewRowPresenter)cp.Parent; 
     Grid g = (Grid)gp.Parent; 
     ListViewItem lvi = (ListViewItem)g.TemplatedParent; 
     lvi.IsSelected = true; 
    } 
0

IMO,最好在代码中设置这一切像这样:

void InitializeDataContext() 
{ 
    var ovens = (from s 
       in dbcontext.Ovens 
       select s).ToList(); 

    ICollectionView view = new CollectionViewSource 
    { 
     Source = ovens 
    }.View; 

    ViewSource = view; 
    ovenListView.ItemsSource = ViewSource; 
} 

您可以调用该方法在你Window_Loaded,消除Window_Loaded其他代码,然后消除绑定,因为你是已经完成了所有的代码。如果在视图(MVVM)中没有任何代码的情况下设置这一切真的会更好,但超出了这个问题的上下文。

+0

设置它建议和CurrentPosition仍然被设置为-1当我选择一个ListItem行。当我最初打开窗口并且没有单击任何行时尝试删除第一行,它被正确设置。CurrentPosition被设置为0,如预期的那样。当我点击一行,风格触发器触发属性没有得到更新。 – MikeC 2011-04-06 19:09:37

+0

你根本不需要那种风格的触发器。这应该全部由WPF使用IsSyncronizedWithCurrentItem和ICollectionView自动处理。 – poindexter12 2011-04-08 14:54:48

0

做了一些测试,问题与样式触发器。

<Trigger Property="IsKeyboardFocusWithin" Value="True"> 
         <Setter Property="IsSelected" Value="True" /> 
        </Trigger> 

我使用的样式触发选择ListViewItem的,当我在ListViewItem的(即文本框/组合框)内的任何点击。当这个触发器到位时,该行将选择是否选择TextBox,但ListCollectionView的CurrentPosition始终为-1。如果我删除触发器并实际选择行本身(单击文本框之外)繁荣的CurrentPosition设置正确。我的问题是为什么...我需要手动设置CurrentPosition。任何帮助赞赏。