4

I'm getting exception:

'{0}' is not a Visual or Visual3D.

The only question I found that similar: WPF: System.ArgumentException => {"'{0}' is not a Visual or Visual3D."}

I'm just building "pretty" grid. No need to handle double-clicks. It's just side-effect when user double-clicks by mistake - this exception throws.

XAML looks like this:

<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>

I get exception whenever user double-clicks. First column is checkbox. When it's single-click-ed it works correct. When I click in any area around checkbox - exception.

How do I fix it? There is no code behind, it's MVVM project

EDIT:

Ok, I went ahead and tried to repro this on small project. I already figured issue but want to know your take on this.. And I need to award this bounty :)

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

Code behind:

namespace WpfApplication1
{
    using System.Windows;

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            this.InitializeComponent();
            this.DataContext = new MainWindowVM();
        }
    }
}
Community
  • 1
  • 1
katit
  • 17,375
  • 35
  • 128
  • 256

4 Answers4

4

Yes. Your sample project throws error now. That's because you've binding with Run. In your first post, you were missing it, so that's why I couldn't reproduce it.

It really seems that it's quite old bug and many users have had it. Knowing microsoft, it wont be fixed anytime soon. (The bug has been part of WPF since beginning I guess). Your best bet is to be clever.

Bind only objects that are Visuals. < Run > is not Visual.

Youll have to make custom TextBlock that will generate correct Runs based on the DataContext without using binding. You need to declare new depedency property which will be part of TextBlock and hook yourself into UIPropertyChanged method, there you will generate Runs().

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
  • 2
    Easier than that... Just mark those Run bindings as Mode=OneWay... Interesting that it will throw meaningful error if I bind to Run from Widget. Only NestedWidget causes this nosense.. – katit Sep 13 '12 at 16:24
0

I can't reproduce the bug. I've copied your code, filled with data, but I can double click everywhere. Are you running .NET4.0?

Either attach your whole program / give me sample code that produces the bug. (Data included etc.)

You should narrow it down to exact binding/UI element that produces this. Is CheckBox responsible for this error? What happens if you remove second column? What if you wrap CheckBox inside Border and set background=Transparent. What if you do this for second column?

Perhaps you can attach MouseLeftButtonDown event listener to somewhere and you can use e.ClickCount==2 to see if the mouseclick indicates that it's part of doubleclick. You can then just handle it, e.Handled=true.

Erti-Chris Eelmaa
  • 25,338
  • 6
  • 61
  • 78
0

Is the DataBinding updated by a background thread? If so than that is the error source. I had a crash like that once and solved it here.

Community
  • 1
  • 1
Johannes
  • 6,490
  • 10
  • 59
  • 108
0

This was a tough one to figure out. I should have just searched Google immediately, as I might have found this information sooner.

I have something to add for those who come after me:

I love the formatting capabilities of a TextBlock, but I (eventually) discovered that using a TextBlock in the CellTemplate was the cause of the

'{0}' is not a Visual or Visual3D.

error.

When customizing the DataGridTemplateColumn, you have the option of specifying a HeaderTemplate, a CellTemplate, and a CellEditingTemplate.

I have had no difficulty using a TextBlock in the HeaderTemplate and the CellEditingTemplate of the DataGrid.

It's only a problem in CellTemplate if the grid allows editing in response to the click. If you're just displaying data and not allowing edit, then TextArea works just fine in CellTemplate.

Mike Stillion
  • 403
  • 1
  • 4
  • 7