使用密钥从ResouceDictionary加载资源x:Shared =" True"

时间:2014-11-12 14:51:21

标签: c# wpf xaml resourcedictionary

在WPF库中,我有一个带有一些模板的资源字典文件,需要通过密钥找到并用作某些控件的内容:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                xmlns:converters="clr-namespace:DbEditor.Converters"
                x:ClassModifier="internal"
                x:Class="DbEditor.Components.ScalarHandlers"
                >
<Grid x:Key="stringEditor" x:Shared="False">
    <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"  IsEnabled="{Binding IsReadOnly}"></TextBox>
</Grid>

<Grid x:Key="intEditor" x:Shared="False">
    <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" PreviewTextInput="IntTextBox_PreviewTextInput" IsEnabled="{Binding IsReadOnly}"></TextBox>
</Grid>
...
</ResourceDictionary>

我以这种方式通过其键找到一个模板:

var scalarDictionary = new ResourceDictionary();
scalarDictionary.Source = new Uri("/DbEditor;component/Components/Scalar.xaml", UriKind.RelativeOrAbsolute);
var pair = scalarDictionary.OfType<DictionaryEntry>().FirstOrDefault(x => (string)x.Key == key);
return pair.Value as FrameworkElement;

但是添加一次控制元素不能在另一个地方使用。在过去,这些模板存储在App.xaml资源中,并具有属性x:Shared =“False”,可以多次使用它们。现在添加x:共享属性会导致运行时错误

"Shared attribute in namespace 'http://schemas.microsoft.com/winfx/2006/xaml' can be used only in compiled resource dictionaries."

我还没有找到任何方法来编译资源字典。将.xaml文件中的构建操作从页面更改为资源,嵌入式资源或编译不会更改任何操作。

有没有办法在运行时通过密钥从ResourceDictionary加载控件并多次使用它们?

2 个答案:

答案 0 :(得分:0)

您可以在资源字典中使用DataTemplates,并在包含控件ContentTemplate属性而不是Content属性上设置它们,因为我假设您当前正在这样做。

您需要更改找到要使用数据模板的键的代码,但这意味着您不需要声明x:shared。

    <DataTemplate x:Key="stringEditor">
       <Grid>
           <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"  IsEnabled="{Binding IsReadOnly}"></TextBox>
       </Grid>
    </DataTemplate>

<ContentControl ContentTemplate="{StaticResource stringEditor}"/>

答案 1 :(得分:0)

问题以一种不雅的方式解决了。我刚刚创建了一个页面,在那里移动资源并用它代替ResourceDictionary:

<Page x:Class="DbEditor.Components.ScalarPage" ...>
    <Page.Resources>
        <Grid x:Key="stringEditor" x:Shared="False">
            <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}"  IsEnabled="{Binding IsReadOnly}"></TextBox>
        </Grid>

        <Grid x:Key="intEditor" x:Shared="False">
            <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" PreviewTextInput="IntTextBox_PreviewTextInput" IsEnabled="{Binding IsReadOnly}"></TextBox>
        </Grid>

    ...

    </Page.Resources>    
</Page>

并且资源加载:

scalarPage = new ScalarPage();               
return scalarPage.FindResource(key) as FrameworkElement;