【问题标题】:Converter of CellEditingTemplate at DataGridTemplateColumn doesn't workDataGridTemplateColumn 的 CellEditingTemplate 转换器不起作用
【发布时间】:2018-12-12 17:24:07
【问题描述】:

XAML:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Persons}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Id}" />
        <DataGridTextColumn Binding="{Binding Name}" />
        <DataGridTemplateColumn Header="Name1" CellEditingTemplate ="{Binding Path=Cars, Converter={StaticResource myConverter}}" />
    </DataGrid.Columns>
</DataGrid>

转换器:

public class myConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is ObservableCollection<Car> test)
        {
            //create the data template
            DataTemplate cardLayout = new DataTemplate();

            foreach (var t in test)
            {
                //set up the stack panel
                FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(StackPanel));
                spFactory.Name = "myComboFactory";
                spFactory.SetValue(StackPanel.OrientationProperty, Orientation.Horizontal);

                //set up the textblock
                FrameworkElementFactory childFactory;
                childFactory = new FrameworkElementFactory(typeof(TextBlock));
                childFactory.SetValue(TextBlock.TextProperty, t.Color);
                spFactory.AppendChild(childFactory);

                //set up the textblock
                childFactory = new FrameworkElementFactory(typeof(TextBlock));
                childFactory.SetValue(TextBlock.TextProperty, t.Speed);
                spFactory.AppendChild(childFactory);

                //set the visual tree of the data template
                cardLayout.VisualTree = spFactory;
            }

            return cardLayout;
        }

        return DependencyProperty.UnsetValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        //Will do.
        return DependencyProperty.UnsetValue;
    }
}

C#:

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }
    public ObservableCollection<Car> Cars { get; set; }
}

public class Car
{
    public string Color { get; set; }
    public int Speed { get; set; }
}

public class ViewModelsWindow2
{
    public ObservableCollection<Person> Persons { get; }

    public ViewModelsWindow2()
    {
        Persons = new ObservableCollection<Person>();
        Persons.Add(new Person() { Id = 177, Name = "John", Cars = new ObservableCollection<Car>() { new Car() { Color = "Green", Speed = 360 } } });
    }
}

我想用一些动态文本框(例如两个文本块)创建自己的 DataGridTemplateColumn。我想通过转换器来做,因为我需要 DataGridTemplateColumn 的双向。我还没有为 ConvertBack 编写代码。 每行的文本框数量会有所不同。

但我有一个问题。转换器不由 WPF 执行。我在Convert开头设置了断点,代码没有停止。

请帮我决定这个问题。我做错了什么?

是这样的。它是静态的,但我想要动态的。

我可能会为 Car 添加属性,而这个人可能有两、三辆......颜色和速度不同的汽车。

数据将由用户编辑。

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Persons}">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Id}" />
        <DataGridTextColumn Binding="{Binding Name}" />
        <DataGridTemplateColumn Header="Name1" CellEditingTemplate ="{Binding Path=Cars, Converter={StaticResource myConverter}}">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <TextBox Text="Green"/>
                                <TextBox Text="360"/>
                            </StackPanel>
                            <StackPanel Orientation="Horizontal">
                                <TextBox Text="Red"/>
                                <TextBox Text="360"/>
                                ...
                            </StackPanel>
                            ...
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

更新:

我将转换器定义为:

xmlns:vm="clr-namespace:WpfApp1.ViewModels"

...

<Window.Resources>
    <ResourceDictionary>
        <vm:myConverter x:Key="myConverter" />
    </ResourceDictionary>
</Window.Resources>
<Window.DataContext>
    <vm:ViewModelsWindow2 />
</Window.DataContext>

【问题讨论】:

  • 换个思路——你为什么不使用CellEditingTemplateSelector?见msdn.microsoft.com/en-us/library/…
  • 您是如何在 XAML 中定义 myConverter 键的?
  • 试试CellEditingTemplate ="{Binding Path=., Converter={StaticResource myConverter}}" 看看你的converter 是否被调用。
  • @user1672994 我更新了帖子。
  • 这个答案声称您不能直接编辑列模板,而是可以模板单元格:stackoverflow.com/questions/10361122/…

标签: c# wpf xaml


【解决方案1】:

您不能像这样绑定到CellEditingTemplate 属性。 DataGridTemplateColumn 不是 FrameworkElement,因此它没有要绑定的 DataContext

你应该做的是使用CellEditingTemplateSelector

public class Selector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        Person person = item as Person;
        if(person != null && person.Cars != null)
        {
            DataTemplate cardLayout = new DataTemplate();

            foreach (Car car in person.Cars)
            {
                //build your template..
            }

            return cardLayout;
        }

        return null;
    }
}

XAML:

<DataGrid AutoGenerateColumns="False" ItemsSource="{Binding Persons}">
    <DataGrid.Resources>
        <local:Selector x:Key="selector" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Id}" />
        <DataGridTextColumn Binding="{Binding Name}" />
        <DataGridTemplateColumn Header="Name1" IsReadOnly="False" CellEditingTemplateSelector="{StaticResource selector}" />
    </DataGrid.Columns>
</DataGrid>

【讨论】:

  • 我可以通过 WPF 表单编辑汽车吗?你有IsReadOnly="False"
  • 我认为我必须在DataGrid的资源中设置selector吗?
  • @Kirill:是的,是的。或者至少您必须在某处定义“选择器”资源。查看我编辑的标记。
  • 感谢您的解决方案。
  • 我还想问一下,反向链接是怎么组织的?我的意思是代码如何知道 WPF 中更改的速度?我必须在SelectTemplate 中使用Binding 类吗?
猜你喜欢
  • 2010-12-08
  • 1970-01-01
  • 2012-04-19
  • 1970-01-01
  • 2016-08-24
  • 2013-02-19
  • 2013-08-15
  • 1970-01-01
  • 2011-04-16
相关资源
最近更新 更多