2011-04-06 105 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。任何幫助讚賞。