无法解析Style,ResourceDictionary,UserControl

时间:2017-04-28 12:47:22

标签: c# wpf xaml user-controls

这是迄今为止我在WPF工作过程中遇到的最令人困惑的问题。该问题有两个组成部分,可能对那些使用WPF的人更长时间表示:

  1. UserControl中,我的ResourceDictionary元素抱怨它需要Key属性。
  2. 当我定义Key属性并尝试在设计时从XAML访问样式时,Intellisense(和编译器)不知道导入的ResourceDictionary中定义的样式。
  3. 我正在尝试将该样式应用于ItemTemplate
  4. 上的。MenuItem

    以下是资源的UserControl XAML声明,注意x:Key属性

    <UserControl.Resources>
        <ResourceDictionary x:Key="HeaderViewStyles">
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../../Styles/Controls/HeaderViewStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    

    以下是ResourceDictionary的部分实现,定义了我希望在MenuItem上使用的样式。

    x:Class="Styles.Controls.HeaderViewStyles">
    
    <Style x:Key="DarkMenuItem" TargetType="{x:Type MenuItem}">
        <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type Menu}}}"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type MenuItem}">
    
     <!---
    

    上述风格本身可能存在问题;但是,我感兴趣的是为什么我无法在设计时访问该风格

    这是我尝试应用样式(发布完整信息):

         <Menu>
            <MenuItem ItemsSource="{Binding ContextMenuItemViewModels}">
                <MenuItem.Icon>
                    <Image Source="../../Resources/menu.png"/>
                </MenuItem.Icon>
                <MenuItem.ItemTemplate>
                    <DataTemplate DataType="{x:Type controlViewModels:ContextMenuItemViewModel}">
                        <MenuItem Style="{DynamicResource DarkMenuItem}"
                            Header="{Binding MenuHeaderText}"
                            Command="{Binding MenuItemClickedCommand}"/>
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>
        </Menu>
    

    我确信这是多种因素的结合;但是,我显然缺乏一些知识。我错过了什么或者没有做什么?我尝试了各种组合,但仍然无法获得风格。

    修改

    对于那些想要更多信息的人,这是我的控制XAML:

    <UserControl x:Class="Views.Controls.HeaderView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:controlViewModels="clr-namespace:ViewModels.Controls"
             xmlns:controlViews="clr-namespace:Views.Controls"
             xmlns:converters="clr-namespace:Converters"
             VerticalContentAlignment="Stretch"
             Background="#4C4C4C">
    
    <UserControl.Resources>
        <converters:SyncStateToVisibilityConverter x:Key="SyncStateToVisibilityConverter"/>
        <ResourceDictionary x:Key="HeaderViewStyles">
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../../Styles/Controls/HeaderViewStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="6"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="60"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="110"/>
        </Grid.ColumnDefinitions>
    
        <Button Background="#4C4C4C" Margin="20,0,0,0" 
                VerticalAlignment="Center" 
                Command="{Binding StatusButtonClickedCommand}">
            <Image >
                <Image.Style>
                    <Style TargetType="{x:Type Image}">
                        <Style.Triggers>
                            <Trigger Property="IsMouseOver" Value="False">
                                <Setter Property="Source" Value="{Binding StatusIconLocation}"/>
                            </Trigger>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Source" Value="{Binding StatusIconLocationHover}"/>
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Image.Style>
            </Image>
        </Button>
    
        <StackPanel Grid.Column="1" Grid.ColumnSpan="2" Orientation="Vertical">
            <TextBlock></TextBlock>
            <TextBlock></TextBlock>
        </StackPanel>
    
        <Menu>
            <MenuItem ItemsSource="{Binding ContextMenuItemViewModels}">
                <MenuItem.Icon>
                    <Image Source="../../Resources/menu.png"/>
                </MenuItem.Icon>
                <MenuItem.ItemTemplate>
                    <DataTemplate DataType="{x:Type controlViewModels:ContextMenuItemViewModel}">
                        <MenuItem Style="{DynamicResource DarkMenuItem}"
                            Header="{Binding MenuHeaderText}"
                            Command="{Binding MenuItemClickedCommand}"/>
                    </DataTemplate>
                </MenuItem.ItemTemplate>
            </MenuItem>
        </Menu>
    
        <ProgressBar Grid.Row="1" 
                    Grid.ColumnSpan="3" 
                    Value="{Binding PercentageSynced}"
                    Visibility="{Binding CurrentSyncSystemStatus, 
                                Converter={StaticResource SyncStateToVisibilityConverter}, 
                                ConverterParameter=Syncing, 
                                FallbackValue=Collapsed}"/>
    </Grid>
    

1 个答案:

答案 0 :(得分:1)

您需要在资源字典中移动转换器,并删除x:Key,如下所示:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="../../Styles/Controls/HeaderViewStyles.xaml"/>
        </ResourceDictionary.MergedDictionaries>
        <converters:SyncStateToVisibilityConverter x:Key="SyncStateToVisibilityConverter"/>
    </ResourceDictionary>
</UserControl.Resources>

如果你把ResourceDictionary没有密钥作为UserControl.Resources的根目录 - 那就意味着:

userControl.Resources = new ResourceDictionary();

所以你必须把里面的所有其他资源放在那个词典中,而不是放在外面。

您的原始xaml(使用x:Key)大致意味着:

userControl.Resources.Add("SyncStateToVisibilityConverter", new YourConverter());
userControl.Resources.Add("HeaderViewStyles", new ResourceDictionary(...));

所以,不是你期望的那样。