wpf可编辑的ListView

时间:2011-05-01 16:22:42

标签: c# wpf listview

我正在尝试使ListView中的字段可编辑。 我的意思是当我在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的Network类,它绑定到listview:

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");
    }
  }
}

2 个答案:

答案 0 :(得分:1)

查看以下链接

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

修改

你可能已经跟着啧啧但是你想念的几件事是导致probs的原因。首先你要尝试使用内置的BooleanToVisibility转换器,但我认为在你的场景中它不会有帮助。你必须创建一个定制像教程中提到的值转换器。

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}" />

进行这些更改,你很高兴....

答案 1 :(得分:0)

为什么不使用数据网格?您可以将其设置为类似于列表的样式,它已经提供了编辑模式功能。您可以使用TemplateColumn提供自定义显示和编辑视图。