Silverlight 默认 ContentPresenter 内容

发布于 2024-10-14 22:19:48 字数 1337 浏览 6 评论 0原文

为什么这不起作用?

在自定义控件的 generic.xaml 中:

在应用于自定义控件的样式中...

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>

...

稍后,在控件模板中...

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}" />

这是 ChromeContent 的依赖属性...

public Object ChromeContent
{
  get { return (Object)GetValue(ChromeContentProperty); }
  set { SetValue(ChromeContentProperty, value); }
}
public static readonly DependencyProperty ChromeContentProperty =
    DependencyProperty.Register("ChromeContent", typeof(Object), 
    typeof(casPopup), null);

正如您所见可以看到,它需要任何物体。我尝试将其更改为网格,但这没有帮助。

它抛出此错误(来自 javascript): _Failed to allocate to property 'System.Windows.Controls.ContentPresenter.Content'

奇怪的是,如果我从设置器中删除网格并仅使用文本,以下内容将正常工作:

<Setter Property="ChromeContent" Value="DEFAULT" />

另外,这将工作也来自控件类中的 OnApplyTemplate 方法:

  Grid g = new Grid();
  g.Width = 100;
  g.Height = 25;
  g.Background = new SolidColorBrush(Colors.LightGray);
  ChromeContent = g;

我很难理解是什么阻止了 generic.xaml 中定义的网格的默认内容工作。有人对此事有了解吗?

非常感谢您的帮助!

Why won't this work?

In generic.xaml for a custom control:

In the style applied to the custom control...

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>

...

Later, in the control template...

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}" />

Here's the dependency property for ChromeContent...

public Object ChromeContent
{
  get { return (Object)GetValue(ChromeContentProperty); }
  set { SetValue(ChromeContentProperty, value); }
}
public static readonly DependencyProperty ChromeContentProperty =
    DependencyProperty.Register("ChromeContent", typeof(Object), 
    typeof(casPopup), null);

As you can see, it takes any object. I tried changing it to a Grid, but that did not help.

It throws this error (from javascript): _Failed to assign to property 'System.Windows.Controls.ContentPresenter.Content'

Oddly, the following will work fine if I remove the Grid from the setter nd just use text:

<Setter Property="ChromeContent" Value="DEFAULT" />

Also, this will work too from the OnApplyTemplate method in the control class:

  Grid g = new Grid();
  g.Width = 100;
  g.Height = 25;
  g.Background = new SolidColorBrush(Colors.LightGray);
  ChromeContent = g;

I'm having a hard time understanding what is preventing the default content of a grid, defined in the generic.xaml from working. Does anyone have any knowledge on this matter?

Many thanks in advance for your help!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

心碎的声音 2024-10-21 22:19:48

这就是问题所在:-

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>

您不应将 UIElement 直接包含在资源字典中或作为样式的值。您可能会将样式视为某种描述符,但事实并非如此。样式中的值是它们所持有的对象的构造实例。您的样式包含 Grid 的单个实例。每当使用该样式分配给 ChromeContent 属性时,它都会尝试分配相同的网格单个实例。

UIElement 只能是一个父级的子级。如果构造您的控件的两个实例,会发生什么情况?将会(如果 silverlight 允许的话)尝试将 Grid 的同一个单个实例分配给两个控件。

这是使用 ControlTemplateDataTemplate 等模板的原因之一。每次使用模板时(而不是首次解析 Xaml 时)都会调用其中的标记。

编辑

要回答您的补充问题,您应该默认另一个DataTemplate类型的属性:-

<Setter Property="ChromeContentTemplate">
  <Setter.Value>
    <DataTemplate>
      <Grid />
    </DataTemplate>
  </Setter.Value>
</Setter>

属性:-

public Object ChromeContentTemplate
{
  get { return (DataTemplate)GetValue(ChromeContentTemplateProperty); }
  set { SetValue(ChromeContentTemplateProperty, value); }
}

public static readonly DependencyProperty ChromeContentTemplateProperty=
    DependencyProperty.Register("ChromeContentTemplate", typeof(DataTemplate), 
    typeof(casPopup), null);

控件模板:-

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}"
     ContentTemplate="{TemplateBinding ChromeContentTemplate" />

This is the problem:-

<Setter Property="ChromeContent">
  <Setter.Value>
    <Grid />
  </Setter.Value>
</Setter>

You should not include a UIElement directly in a resource dictionary or as a value of a style. You might see the style as being some kind of descriptor but it isn't. The values in a style are constructed instances of the objects they hold. Your style holds a single instance of Grid. Whenever that style is used to assign to a ChromeContent property it will attempt to assing the same single instance of the Grid.

A UIElement can only be a child of one parent. What would happen if two instances your control were constructed? There would (if silverlight let you) be an attempt to assign the same single instance of the Grid to both controls.

This is one reason for templates such as ControlTemplate and DataTemplate. The markup inside these is invoked each time the template is used rather than when the Xaml is first parsed.

Edit:

To answer you supplementary question, you should default another property of type DataTemplate:-

<Setter Property="ChromeContentTemplate">
  <Setter.Value>
    <DataTemplate>
      <Grid />
    </DataTemplate>
  </Setter.Value>
</Setter>

Property:-

public Object ChromeContentTemplate
{
  get { return (DataTemplate)GetValue(ChromeContentTemplateProperty); }
  set { SetValue(ChromeContentTemplateProperty, value); }
}

public static readonly DependencyProperty ChromeContentTemplateProperty=
    DependencyProperty.Register("ChromeContentTemplate", typeof(DataTemplate), 
    typeof(casPopup), null);

Control Template:-

<ContentPresenter Grid.Column="0" 
     x:Name="ChromeContentPresenter" 
     Content="{TemplateBinding ChromeContent}"
     ContentTemplate="{TemplateBinding ChromeContentTemplate" />
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文