datagrid Cell中的WPF AutocompeteBox无法正常工作

时间:2015-06-18 11:51:17

标签: wpf datagrid autocomplete

我正在测试datagrid单元格中的WPF AutoCompleteBox控件。 我遇到了两个问题:

1)当我导航到自动完成单元格时,它不会自动切换到编辑模式,

2)当我切换到编辑模式并输入内容时,没有出现suggesstions列表,关闭窗口后,我有一个调试错误,上面写着:

System.Windows.Data错误:40:BindingExpression路径错误:'对象'''人物'(HashCode = 40808136)'上找不到'名称'属性。 BindingExpression:路径=名称; DataItem ='Person'(HashCode = 40808136); target元素是'AutoCompleteBox'(Name ='acb2'); target属性是'ItemsSource'(类型'IEnumerable')

这里是代码

namespace WpfPlayingWithDatagrid
{
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        MyViewModel mv = new MyViewModel();
        this.DataContext = mv;


    }
}
}

public class MyViewModel : ObservableObject
{
    ObservableCollection<Person> _names = null;

    RelayCommand _loadClients;
    RelayCommand _showSelectedPerson;

    Person _selectedPerson;

    public Person SelectedPerson
    {
        get { return _selectedPerson; }
        set { _selectedPerson = value; }
    }



    public ObservableCollection<Person> Names
    {
        get { return _names; }
        set { _names = value;
        RaisePropertyChanged("Names");
        }
    }


    public RelayCommand LoadClientCommand
    {
        get
        {
            if (_loadClients == null)
                _loadClients = new RelayCommand(LoadCommandExecute);
            return _loadClients;
        }
    }



    private void LoadCommandExecute()
    {
        LoadClients();
    }



    public void LoadClients()
    {
        List<Person> ll = new List<Person>(5);
        ll.Add(new Person(1,"ETS CUSTOMER1","Addresse1"));
        ll.Add(new Person(2,"COMPX CUSTOMER2","Addresse 2"));
        ll.Add(new Person(3,"ENTREPRISE3","Adresse3"));
        ll.Add(new Person(4,"SOCIETE X4HERTZ","Addresse4"));
        ll.Add(new Person(5,"CARCOMP","Addresse5"));

        Names   = new ObservableCollection<Person>(ll);

    }



    public RelayCommand ShowSelectedPersonCommand
    {
        get
        {
            if (_showSelectedPerson == null)
                _showSelectedPerson = new RelayCommand(ShowSelectedPersonCommandExecute);
            return _showSelectedPerson;
        }
    }



    private void ShowSelectedPersonCommandExecute()
    {
        if (SelectedPerson != null)
                        MessageBox.Show(SelectedPerson.Nom);
        else
            MessageBox.Show("No selection.");

    }

}}

和XAML如下:

<Window x:Class="WpfPlayingWithDatagrid.MainWindow"
    x:Name="wnd"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
    xmlns:gs="http://www.galasoft.ch/mvvmlight"
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input.Toolkit"
    xmlns:local="clr-namespace:WpfPlayingWithDatagrid"
    Title="MainWindow" >

<Window.Resources>
    <local:MyViewModel x:Key="MyViewModel"/>

    <Style x:Key="acbStyle" TargetType="controls:AutoCompleteBox">
        <Setter Property="FilterMode" Value="Contains"/>
        <Setter Property="IsTextCompletionEnabled" Value="True"/>
    </Style> 
    <DataTemplate x:Key="AutoCompleteBoxItemTemplate">
        <StackPanel Orientation="Horizontal">
            <Label Content="{Binding Code}"  Width="20" />
            <Label Content="{Binding Nom}"/>
         </StackPanel>
    </DataTemplate>
</Window.Resources>
<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>

    <Grid.RowDefinitions>
        <RowDefinition Height="50"/>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
        <Button Grid.Column="1" 
                Content="Load Customers" 
                Command="{Binding LoadClientCommand}" Margin="10"/>
                <DataGrid Grid.Row="1" 
                          Grid.ColumnSpan="3"
                          AutoGenerateColumns="False" 
                          HorizontalAlignment="Stretch" 
                          VerticalAlignment="Stretch"  
                          RowHeight="30"
                          Grid.Column="0" 
                          SelectionUnit="Cell"
                          ItemsSource="{Binding  Names, 
                      UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" 
                         Grid.RowSpan="2"
                >
        <DataGrid.Columns>
            <DataGridTextColumn 
             Binding="{Binding Code,  Mode=TwoWay, StringFormat=\{0:#\}}"  Header="Code" />
            <DataGridTemplateColumn Header="Name" >

               <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Nom}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
                <DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <controls:AutoCompleteBox
                                x:Name="acb2"
                                Text="{Binding Nom}" 
                                ItemsSource="{Binding Names}"  
                                ValueMemberBinding="{Binding Nom}"
                                Style="{StaticResource acbStyle}"
                                ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"
                                />
                        </DataTemplate>
                </DataGridTemplateColumn.CellEditingTemplate>

        </DataGridTemplateColumn>
       <DataGridTextColumn Binding="{Binding Adresse, Mode=TwoWay,      UpdateSourceTrigger=PropertyChanged}"       Header="Adresse" />
        </DataGrid.Columns>
        </DataGrid>
      </Grid>
     </Window>

和人类:

 namespace WpfPlayingWithDatagrid
{
  public class Person
  {
    int code;

    public int Code
    {
        get { return code; }
        set { code = value; }
    }
    string nom;

    public string Nom
    {
        get { return nom; }
        set { nom = value; }
    }
    string adresse;

    public string Adresse
    {
        get { return adresse; }
        set { adresse = value; }
    }



    public Person(int c, string n, string a)
    {
        Code = c;
        Nom = n;
        Adresse = a;

    }
}
}

提前谢谢。

1 个答案:

答案 0 :(得分:0)

由于DataGridColumns的实现方式,绑定到父视图模型总是有问题的。

您收到绑定错误的原因是因为该行绑定到Person,而Person没有Names属性。

names属性出现在MyViewModel上,可以像这样访问

<controls:AutoCompleteBox
  x:Name="acb2"
  Text="{Binding Nom}" 
  ItemsSource="{Binding Names,Source={StaticResource MyViewModel}}"  
  ValueMemberBinding="{Binding Nom}"
  Style="{StaticResource acbStyle}"
  ItemTemplate="{StaticResource AutoCompleteBoxItemTemplate}"
 />

<强>更新

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        MyViewModel mv = (MyViewModel) FindResource("MyViewModel");
        this.DataContext = mv;

    }
}