如何摆脱恼人的Horizo​​ntalContentAlignment绑定警告?

时间:2010-04-19 10:00:18

标签: .net wpf xaml binding

我正在开发一个大型WPF项目,在调试期间,我的输出窗口充满了这些恼人的警告:

  

System.Windows.Data信息:10:无法使用绑定检索值且无效>存在回退值;使用默认值。   的 BindingExpression:路径= Horizo​​ntalContentAlignment; DataItem = null; 目标元素是   ' ComboBoxItem '(Name =''); target属性是'Horizo​​ntalContentAlignment'(类型>'   的Horizo​​ntalAlignment')

在具体示例中,ComboBoxItem以这种方式设置样式:

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="SnapsToDevicePixels" Value="True"/>                  
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ComboBoxItem}">
                <Border 
                    Name="bd"
                    Padding="4,4,4,4"
                    SnapsToDevicePixels="True" 
                    CornerRadius="2,2,2,2">
                    <ContentPresenter />
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsHighlighted" Value="true">
                        <Setter TargetName="bd" Property="Background"  Value="{StaticResource MediumBrush}"/>
                        <Setter TargetName="bd" Property="Padding"  Value="4,4,4,4"/>
                        <Setter TargetName="bd" Property="CornerRadius"  Value="2,2,2,2"/>
                    </Trigger>
                </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

我知道问题是由 ComboBoxItem 的默认主题定义生成的,其中包含以下内容:

<Setter Property="Control.HorizontalContentAlignment">
        <Setter.Value>
            <Binding Path="HorizontalContentAlignment" RelativeSource="{RelativeSource Mode=FindAncestor, AncestorType=ItemsControl, AncestorLevel=1}" />
            </Setter.Value>
        </Setter>

但我也认为使用

<Setter Property="OverridesDefaultStyle" Value="True"/> 

将解决问题,而警告仍然存在。

编辑:为了重现这个问题,您还需要覆盖ComboBox的样式,就像在MSDN中这个示例中完成的那样: ComboBox ControlTemplate Example

非常感谢任何帮助

4 个答案:

答案 0 :(得分:9)

这对我有用。将它放在Application.xaml文件中。

<Application.Resources>
    <Style TargetType="ComboBoxItem">
        <Setter Property="HorizontalContentAlignment" Value="Left" />
        <Setter Property="VerticalContentAlignment" Value="Center" />
    </Style>
</Application.Resources>

...从

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/42cd1554-de7a-473b-b977-ddbd6298b3d0

答案 1 :(得分:1)

我不知道一年多后你是否仍然对这个问题感兴趣,但我的解决方案是明确地在风格中写出这个值。例如:

<Style x:Key="{x:Type ComboBoxItem}" TargetType="{x:Type ComboBoxItem}">
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>

这就解决了这个问题。

答案 2 :(得分:1)

同样的问题是'MenuItem',如果它直接放在像'StackPanel'等面板中。可以使用上面的Carter答案修复,只需将'ComboBoxItem'替换为'Style'中的'MenuItem'

答案 3 :(得分:0)

我只想提一下我在两天内遇到类似问题(我的“Windows数据错误4”错误,抱怨HorizontalContentAlignmentVerticalContentAlignment)。

最常见的建议解决方案(将Horizo​​ntal / VerticalContentAlignment样式添加到元素,甚至添加到App.xaml)并不总能解决问题。

最终,我发现了一些与我自己的情况有关的东西 - 我希望它对某人有所帮助:如果您使用的是FilterEventHandler,请不要在重新订阅之前取消订阅!

每当我更改频道过滤器(调用UpdateCorporatesList)时,我的旧代码就会一直生成“数据错误4”消息:

// This code generates errors
private void UpdateCorporatesList()
{
    this.CorporatesViewSource.Filter -= new FilterEventHandler(ApplyCorporateFilter);

    if (this.ChannelFilter != null)
    {
        this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);
    }
    else
    {
        this.CorporateFilter = null;
    }
}

private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
    SalesCorporate customer = e.Item as SalesCorporate;
    var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter).Description;
    if ((customer.ID != null) && (customer.Channel != currentChannel))
    {
        e.Accepted = false;
    }
}

...所以我每次都改为重新订阅FilterEventHandler,而是在事件处理方法中对Channel Filter进行null检查。

// This code works as intended
private void UpdateCorporatesList()
{
    this.CorporatesViewSource.Filter += new FilterEventHandler(ApplyCorporateFilter);

    if (this.ChannelFilter == null)
    {
        this.CorporateFilter = null;
    }
}

private void ApplyCorporateFilter(object sender, FilterEventArgs e)
{
    var currentChannel = this.Channels.FirstOrDefault(x => x.ID == this.ChannelFilter);
    if (currentChannel.ID == null)
    {
        return;
    }

    SalesCorporate customer = e.Item as SalesCorporate;
    if ((customer.ID != null) && (customer.Channel != currentChannel.Description))
    {
        e.Accepted = false;
    }
}

Et Voila!没有更多错误: - )