DataGridTemplateColumn - DoubleClick时的例外情况

时间:2012-09-10 20:23:47

标签: c# wpf xaml wpfdatagrid

我得到例外:

  

'{0}'不是Visual或Visual3D。

我发现类似的唯一问题:WPF: System.ArgumentException => {"'{0}' is not a Visual or Visual3D."}

我只是在构建“漂亮”的网格。无需处理双击。当用户误击双击时,这只是副作用 - 这个异常会抛出。

XAML看起来像这样:

<DataGrid
  ItemsSource="{Binding Source={StaticResource TrucksSource}}"
  CanUserReorderColumns="False" 
  CanUserResizeColumns="True" 
  CanUserResizeRows="False" 
  AutoGenerateColumns="False" 
  BorderThickness="0" 
  CanUserAddRows="False" 
  RowBackground="{StaticResource GrayBackgroundGradientBrush}"
  RowHeight="20" Focusable="False" RowHeaderWidth="0">
  <DataGrid.Columns>
      <DataGridTemplateColumn Header="Select" Width="40" CanUserSort="True" SortMemberPath="IsSelected">
          <DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                  <CheckBox
                      IsChecked="{Binding IsSelected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                      HorizontalAlignment="Center"
                      VerticalAlignment="Center" />
              </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>
      <DataGridTemplateColumn Header="Team" Width="42" CanUserSort="True" SortMemberPath="TeamDispatcherCaptionShort">
          <DataGridTemplateColumn.CellTemplate>
              <DataTemplate>
                  <Border
                  Margin="-2,-1">
                      <TextBlock ToolTip="{Binding TeamDispatcherCaptionLong}" 
                      Foreground="#414141" FontFamily="Arial" FontSize="12"
                      Text="{Binding TeamDispatcherCaptionShort}" 
                      HorizontalAlignment="Center" VerticalAlignment="Center" />
                  </Border>
              </DataTemplate>
          </DataGridTemplateColumn.CellTemplate>
      </DataGridTemplateColumn>

每当用户双击时我都会遇到异常。第一列是复选框。当它单击时,它的工作正确。当我点击复选框周围的任何区域时 - 例外。

我该如何解决?没有代码,它是MVVM项目

编辑:

好的,我继续尝试在小项目上重复这个。我已经想出了问题,但想知道你对此的看法......我需要奖励这个奖励:)

<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ResourceDictionary>
            <CollectionViewSource x:Key="WidgetsSource" Source="{Binding Widgets}" />
        </ResourceDictionary>
    </Window.Resources>
    <Grid>
        <DataGrid
            ItemsSource="{Binding Source={StaticResource WidgetsSource}}"
            CanUserReorderColumns="False" 
            CanUserResizeColumns="True" 
            CanUserResizeRows="False" 
            AutoGenerateColumns="False" 
            BorderThickness="0" 
            CanUserAddRows="False" 
            VerticalGridLinesBrush="#00000000" 
            HorizontalGridLinesBrush="Gray" 
            RowBackground="LightGray"
            RowHeight="20" Focusable="False" RowHeaderWidth="0" SelectionUnit="Cell">
            <DataGrid.Columns>
                <DataGridTemplateColumn Header="Prop1" Width="50" CanUserSort="True" SortMemberPath="Prop1">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock>
                                    <Run Text="{Binding NestWidg.Prop1}" />
                                </TextBlock>
                            </Border>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                <DataGridTemplateColumn Header="Prop2" Width="50" CanUserSort="True" SortMemberPath="Prop1">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Border>
                                <TextBlock Text="{Binding Prop1}" />
                            </Border>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>                
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

VM:

namespace WpfApplication1
{
    using System.Collections.ObjectModel;

    public class MainWindowVM
    {
        public ObservableCollection<Widget> Widgets { get; set; }

        public MainWindowVM()
        {
            this.Widgets = new ObservableCollection<Widget>();

            this.Widgets.Clear();
            this.Widgets.Add(new Widget("a", "b") { NestWidg = new NestWidget { Prop1 = "Nest" } });
        }
    }

    public class Widget
    {
        public Widget(string p1, string p2)
        {
            Prop1 = p1;
            Prop2 = p2;
        }

        public string Prop1 { get; private set; }

        public string Prop2 { get; private set; }

        public NestWidget NestWidg { get; set; }
    }

    public class NestWidget
    {
        public string Prop1 { get; set; }
    }
}

代码背后:

namespace WpfApplication1
{
    using System.Windows;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = new MainWindowVM();
        }
    }
}

4 个答案:

答案 0 :(得分:4)

是。您的示例项目现在抛出错误。那是因为你与Run绑定了。在你的第一篇文章中,你错过了它,所以这就是为什么我无法重现它。

看起来它确实是一个很老的错误而且很多用户已经拥有它。知道微软,它不会很快修复。 (自从我猜测以来,这个bug一直是WPF的一部分)。 你最好的选择是要聪明。

仅绑定Visuals对象。 &LT;运行&gt;不是视觉。

您必须制作自定义TextBlock,它将根据DataContext生成正确的运行而不使用绑定。你需要声明一个新的依赖属性,它将成为TextBlock的一部分并将你自己挂钩到UIPropertyChanged方法中,你将生成Runs()。

答案 1 :(得分:0)

我无法重现这个错误。我已经复制了你的代码,里面装满了数据,但我可以随处双击。你在运行.NET4.0吗?

附上整个程序/给我产生错误的示例代码。 (包括数据等)

您应该将其缩小到产生此效果的精确绑定/ UI元素。 CheckBox是否对此错误负责? 如果删除第二列会发生什么? 如果将CheckBox包装在Border中并设置background = Transparent,该怎么办? 如果你为第二列做这个怎么办?

也许你可以将MouseLeftButtonDown事件监听器附加到某个地方,你可以使用e.ClickCount == 2来查看mouseclick是否表明它是doubleclick的一部分。然后你可以处理它,e.Handled = true。

答案 2 :(得分:0)

DataBinding是否由后台线程更新? 如果是这样的错误来源。 我遇到过这样的一次崩溃并解决了它here

答案 3 :(得分:0)

这是一个很难理解的问题。我应该立即搜索谷歌,因为我可能会更早地找到这些信息。

我有些东西可以为那些追随我的人添加:

我喜欢TextBlock的格式化功能,但我(最终)发现在TextBlock中使用CellTemplate

的原因
  

&#39; {0}&#39;不是Visual或Visual3D。

错误。

自定义DataGridTemplateColumn时,您可以选择指定HeaderTemplateCellTemplateCellEditingTemplate

我使用TextBlock中的HeaderTemplateCellEditingTemplate的{​​{1}}毫无困难。

如果网格允许编辑以响应点击,那么DataGrid只会出现问题。如果您只是显示数据而不允许编辑,则CellTemplateTextArea中工作正常。