2011-05-01 184 views
1

我想在ListView中編輯一個字段。 我的意思是當我在列表視圖中選擇行時,一個字段變爲文本框而不是文本塊。 但它不起作用 - 我一直都在看到兩個控件。wpf可編輯ListView

XAML:

<Window x:Class="fastnn_speedTest.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:sys="clr-namespace:System;assembly=mscorlib" 
xmlns:local="clr-namespace:fastnn_speedTest" 
DataContext="{Binding RelativeSource={RelativeSource Self}}" 
Title="fastnn: not saved" Height="300" Width="300"> 

<Window.Resources> 

    <local:BoolToVisibilityConverter x:Key="VisibilityOfBool" /> 
    <local:StringToIntValueConverter x:Key="StringToInt" /> 
    <local:StringToFloatValueConverter x:Key="StringToFloat" /> 

    <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="ActivationEnum"> 
     <ObjectDataProvider.MethodParameters> 
      <x:Type x:TypeName="local:Network+Layer+ActivFunction" /> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 

    <ObjectDataProvider MethodName="GetValues" ObjectType="{x:Type sys:Enum}" x:Key="ComputeMethodEnum"> 
     <ObjectDataProvider.MethodParameters> 
      <x:Type x:TypeName="local:Training+ComputeMethodEnum" /> 
     </ObjectDataProvider.MethodParameters> 
    </ObjectDataProvider> 

    <Style TargetType="{x:Type TextBlock}" x:Key="ListTextBlockStyle"> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
     <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource VisibilityOfBool}, ConverterParameter=True}" /> 
    </Style> 

    <Style TargetType="{x:Type FrameworkElement}" x:Key="ListTextBoxStyle"> 
     <Setter Property="VerticalAlignment" Value="Center" /> 
     <Setter Property="Visibility" Value="{Binding Path=IsSelected, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Converter={StaticResource VisibilityOfBool}, ConverterParameter=False}" /> 
    </Style> 

    <DataTemplate x:Key="ActivationTemplate"> 
     <ComboBox ItemsSource="{Binding Source={StaticResource ActivationEnum}}" SelectedValue="{Binding Path=Activation}" Width="100"/> 
    </DataTemplate> 

    <DataTemplate x:Key="NeuronsTemplate"> 
     <Grid> 
      <TextBox Text="{Binding Path=Neurons}" Width="40" Style="{Binding Source=StaticResource ListTextBoxStyle }"></TextBox> 
      <TextBlock Text="{Binding Path=Neurons}" Width="40" Style="{Binding Source=StaticResource ListTextBlockStyle }"></TextBlock> 
     </Grid> 
    </DataTemplate> 

</Window.Resources> 

<Grid Background="LightGray"> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="auto"></RowDefinition> 
     <RowDefinition Height="*"></RowDefinition> 
     <RowDefinition Height="auto"></RowDefinition> 
    </Grid.RowDefinitions> 
    <Menu Grid.Row="0"> 
     <MenuItem Header="File"> 
      <MenuItem Header="New" Click="MenuNew_Click"></MenuItem> 
      <MenuItem Header="Open" Click="MenuOpen_Click"></MenuItem> 
      <Separator></Separator> 
      <MenuItem Header="Save" Click="MenuSave_Click"></MenuItem> 
      <MenuItem Header="Save As" Click="MenuSaveAs_Click"></MenuItem> 
      <Separator></Separator> 
      <MenuItem Header="Exit"></MenuItem> 
     </MenuItem> 
    </Menu> 
    <TabControl Grid.Row="1" Name="Tabs"> 
     <TabItem Header="Network"> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="*"></RowDefinition> 
        <RowDefinition Height="auto"></RowDefinition> 
       </Grid.RowDefinitions> 
       <ListView Grid.Row="0" x:Name="NetworkListview" ItemsSource="{Binding network.Layers}" IsSynchronizedWithCurrentItem="True"> 
        <ListView.View> 
         <GridView> 
          <GridViewColumn Width="100" Header="layer name" DisplayMemberBinding="{Binding Name}"/> 
          <GridViewColumn Width="60" Header="neurons" CellTemplate="{StaticResource NeuronsTemplate}"/> 
          <GridViewColumn Width="110" Header="activation" CellTemplate="{StaticResource ActivationTemplate}"/> 
         </GridView> 
        </ListView.View> 
       </ListView> 
       <UniformGrid Grid.Row="1" Rows="1"> 
        <Button Name="AddLayerButton" Click="AddLayerButton_Click">Add layer</Button> 
        <Button Name="RemoveLayerButton" Click="RemoveLayerButton_Click">Remove layer</Button> 
       </UniformGrid> 
      </Grid> 
     </TabItem> 
     <TabItem Header="Data set"> 
      <UniformGrid Columns="2" Height="70" Width="220"> 
       <Label>input dimmension</Label> 
       <TextBox Text="{Binding Path=data_set.InputDimmension, Mode=TwoWay, Converter={StaticResource StringToInt}}"></TextBox> 
       <Label>output dimmension</Label> 
       <TextBox Text="{Binding Path=data_set.OutputDimmension, Mode=TwoWay, Converter={StaticResource StringToInt}}"></TextBox> 
       <Label>number of samples</Label> 
       <TextBox Text="{Binding Path=data_set.SamplesNumber, Mode=TwoWay}"></TextBox> 
      </UniformGrid> 
     </TabItem> 
     <TabItem Header="Training"> 
      <UniformGrid Columns="2" Width="230" Height="170"> 
       <Label>learning rate</Label> 
       <TextBox Text="{Binding Path=training.LearningRate, Mode=TwoWay, Converter={StaticResource StringToFloat}}"></TextBox> 
       <Label>epochs</Label> 
       <TextBox Text="{Binding Path=training.Epochs, Mode=TwoWay, Converter={StaticResource StringToInt}}"></TextBox> 
       <Label>weights stddev</Label> 
       <TextBox Text="{Binding Path=training.WeightsStddev, Mode=TwoWay, Converter={StaticResource StringToFloat}}"></TextBox> 
       <Label>srand(0)</Label> 
       <CheckBox Margin="0,4,0,0" IsChecked="{Binding Path=training.SrandZero}"></CheckBox> 
       <Label>compute method</Label> 
       <ComboBox Name="ComputeMethodCombo" ItemsSource="{Binding Source={StaticResource ComputeMethodEnum}}" SelectedValue="{Binding Path=training.ComputeMethod}"></ComboBox> 
       <Label>select device</Label> 
       <ComboBox Name="DeviceComboBox" SelectedIndex="{Binding Path=training.DeviceIndex}"></ComboBox> 
       <Label>click to run test</Label> 
       <Button Margin="2" Name="RunTestButton" Click="RunTestButton_Click">Run test</Button> 
      </UniformGrid> 
     </TabItem> 
     <TabItem Header="Output"> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="*"></RowDefinition> 
        <RowDefinition Height="auto"></RowDefinition> 
       </Grid.RowDefinitions> 
       <TextBox Grid.Row="0" Name="LogTextBox"></TextBox> 
       <UniformGrid Grid.Row="1" Rows="1"> 
        <Button>Save</Button> 
        <Button Name="ClearButton" Click="ClearButton_Click">Clear</Button> 
        <Button>Eerror chart</Button> 
        <Button>Speed chart</Button> 
       </UniformGrid> 
      </Grid> 
     </TabItem> 
    </TabControl> 
    <StatusBar Grid.Row="2"> 
     <StatusBarItem> 
      <TextBlock>text</TextBlock> 
     </StatusBarItem> 
    </StatusBar> 
</Grid> 

轉換器:

public class BoolToVisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool param = bool.Parse(parameter as string); 
     bool val = (bool)value; 

     return val == param ? Visibility.Visible : Visibility.Hidden; 
    } 

    public object ConvertBack(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

,幷包含這勢必列表視圖的ObservableCollection網絡類:

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Collections.ObjectModel; 
using System.ComponentModel; 
using System.Windows; 
using System.Xml.Serialization; 

namespace fastnn_speedTest 
{ 

    public class Network 
    { 
    public class Layer : INotifyPropertyChanged 
    { 
     public enum ActivFunction { LINEAR, EXPONENTIAL, ARCUSTANGENT } 

     private string name; 

     [XmlIgnore] 
     public string Name 
     { 
      get 
      { 
       return name; 
      } 
      set 
      { 
       name = value; 
       RaisePropertyChanged("Name"); 
      } 
     } 

     [XmlAttribute] 
     public ActivFunction Activation { get; set; } 

     [XmlAttribute] 
     public int Neurons { get; set; } 

     public event PropertyChangedEventHandler PropertyChanged; 

     protected virtual void RaisePropertyChanged(String propertyName) 
     { 
      if (PropertyChanged != null) 
      { 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
     } 

    } 

    public ObservableCollection<Layer> Layers { get; set; } 

    public Network() 
    { 
     Layers = new ObservableCollection<Layer>(); 
    } 

    public void AddLayer(Layer layer) 
    { 
     int last = Layers.Count; 
     if (last > 0) 
     { 

      Layers.Last().Name = "Layer " + last + " (hidden)"; 
     } 
     layer.Name = "Layer " + (last + 1) + " (output)"; 
     Layers.Add(layer); 
    } 

    public void RemoveLayer(int index) 
    { 
     if(index >= 0 && index < Layers.Count) 
      Layers.RemoveAt(index); 
    } 

    public void Clear() 
    { 
     Layers.Clear(); 
    } 

    public void Validate() 
    { 
     if (Layers.Count < 1) 
      throw new ArgumentException("minimum number of layers is 1"); 

     foreach (Layer layer in Layers) 
     { 
      if (layer.Neurons <= 0) 
       throw new ArgumentException("neurons in each layer must be > 0"); 
     } 

     if(Layers.Last().Activation != Layer.ActivFunction.LINEAR) 
      throw new ArgumentException("last layer must be linear"); 
    } 
    } 
} 
+0

你可以發佈轉換器的代碼?我懷疑問題出在那裏,因爲你正在發送顯式的轉換器參數。 – 2011-05-01 16:40:17

+0

我沒有實現轉換器 - 這是WPF默認的... – user606521 2011-05-01 17:10:48

回答

1

看一看在下面的鏈接

http://www.switchonthecode.com/tutorials/wpf-tutorial-using-the-listview-part-3-in-place-edit

編輯

您可能已經跟隨你錯過的東西嘖嘖,但夫妻是什麼導致你試圖使用內置的BooleanToVisibility轉換器的probs.First但我認爲在你的場景中它不會有幫助。你必須創建一個像教程中提到的自定義值轉換器。

public class BoolToVisibilityConverter : IValueConverter 
    { 
    public object Convert(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     bool param = bool.Parse(parameter as string); 
     bool val = (bool)value; 

     return val == param ? Visibility.Visible : Visibility.Hidden; 
    } 

    public object ConvertBack(object value, Type targetType, 
     object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
    } 

你也不得不提你的轉換器這樣

<Setter Property="Visibility" Value="{Binding Path=IsSelected, 
     RelativeSource={RelativeSource FindAncestor, 
     AncestorType={x:Type ListViewItem}}, 
     Converter={StaticResource VisibilityOfBool}, ConverterParameter=False}" /> 

做這些改變,你是好去....

+0

是的,我用這個教程...但它不適合我... – user606521 2011-05-01 17:11:42

+0

我做到了這一切,仍然是相同的 - 我看到兩個文本塊和文本框 – user606521 2011-05-01 21:04:45

+0

它爲我工作。發佈您的完整代碼 – biju 2011-05-02 04:02:00

0

你爲什麼不使用數據網格?您可以將其設置爲一個列表,並且它已經提供了編輯模式功能。您可以使用TemplateColumn來提供自定義顯示和編輯視圖。