C# 如何重用Xamarin.Forms中父ContentView中定义的样式

C# 如何重用Xamarin.Forms中父ContentView中定义的样式,c#,xaml,xamarin,xamarin.forms,C#,Xaml,Xamarin,Xamarin.forms,首先,我有一个名为FieldView的组件,其定义如下: <?xml version="1.0" encoding="utf-8" ?> <ContentView xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="CustomViews.Components.Fields.FieldView"&

首先,我有一个名为
FieldView
的组件,其定义如下:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    x:Class="CustomViews.Components.Fields.FieldView">

    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="LabelStyle" TargetType="Label">
                <Setter Property="FontSize" Value="20"></Setter>
        </ResourceDictionary>
    </ContentView.Resources>

    <StackLayout>
        <Label Text="Hello world" Style="{StaticResource LabelStyle}"></Label>
    </StackLayout>

</ContentView>
问题是我无法在
TextFieldView
组件中使用
FieldView
中定义的样式


是否有一种方法可以引用
FieldView
组件内部
TextFieldView
中定义的样式?即:访问父组件中定义的样式。我是否应该以任何方式使用代码隐藏文件?

如果您在整个应用程序的多个视图中使用相同的
样式
,我可能会将您的样式移动到
app.xaml中,然后从那里使用它

但是,如果
textfieldwiew
基类设置为
FieldView
,但从代码中看,您的资源没有在其中正确定义,并且缺少一个结束
,则您尝试执行的操作应该有效。例如,当我试用并在xaml页面中使用
TextFieldView
时,下面的代码就起作用了

现场视图:

<ContentView 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="TestApp.Forms.FieldView">
    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="LabelStyle" TargetType="Label">
                <Setter Property="FontSize" Value="40" />
            </Style>
        </ResourceDictionary>
    </ContentView.Resources>
    <StackLayout>
        <Label Text="Hello world" Style="{StaticResource LabelStyle}" />
    </StackLayout>
</ContentView>
<local:FieldView 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:NuclearHalfLife.Forms" 
    x:Class="TestApp.Forms.TextFieldView">
    <StackLayout>
        <Label Text="Hello from TextFieldView" Style="{StaticResource LabelStyle}" />
    </StackLayout>
</local:FieldView>

TextFieldView:

<ContentView 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    x:Class="TestApp.Forms.FieldView">
    <ContentView.Resources>
        <ResourceDictionary>
            <Style x:Key="LabelStyle" TargetType="Label">
                <Setter Property="FontSize" Value="40" />
            </Style>
        </ResourceDictionary>
    </ContentView.Resources>
    <StackLayout>
        <Label Text="Hello world" Style="{StaticResource LabelStyle}" />
    </StackLayout>
</ContentView>
<local:FieldView 
    xmlns="http://xamarin.com/schemas/2014/forms" 
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:local="clr-namespace:NuclearHalfLife.Forms" 
    x:Class="TestApp.Forms.TextFieldView">
    <StackLayout>
        <Label Text="Hello from TextFieldView" Style="{StaticResource LabelStyle}" />
    </StackLayout>
</local:FieldView>

尼克的回答真的很有效,只是语法错误,我无法想象你的应用程序是如何运行的

但是,如果创建一个方法来提供
ResourceDictionary
,而不是在XAML上定义它,则可以扩展样式(以及任何其他资源)。因此,您的基础视图将如下所示:

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="CustomViews.Components.Fields.FieldView">
    <StackLayout>
        <Label Text="Hello world" 
               Style="{StaticResource LabelStyle}"/>
    </StackLayout>
</ContentView>
在您的子视图中,您应该像在base上一样设置
Resources
属性,并根据需要添加新资源:

[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class ChildView : FieldView
{
    public ChildView()
    {
        InitializeComponent();
        // Call the same method
        Resources = GetResources();
    }

    protected override ResourceDictionary GetResources()
    {
        ResourceDictionary res = base.GetResources();

        // You can add new Styles here, for example
        Style newStyle = new Style(typeof(Button));
        newStyle.Setters.Add(new Setter() { Property = Button.BackgroundColorProperty, Value = Color.Red });

        res.Add("DangerButtonStyle", newStyle);

        return res;
    }
}

我希望它会有用。

从新内容页定义一个单独的ResourceDictionary,并使用:

可以在
ContentView
中引用单独资源字典中的样式:

xmlns:resDictStyles="clr-namespace:MyNamespace"
...
<ContentView.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <resDictStyles:MyStyles />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</ContentView.Resources>
...
<Label Style="{StaticResource LabelResDictStyle}" />

嗨,迭戈!事实上,我的答案有输入错误,但我的代码没有。错误来自创建问题时的复制、粘贴和编辑过程。奇怪的是,我的代码在一个重建过程后工作了。我接受你的回答是因为你关于
GetResources
方法的提示最适合我的需要。非常感谢。
namespace MyNamespace
{
  [XamlCompilation(XamlCompilationOptions.Compile)]
  public partial class MyStyles : ResourceDictionary
  {
    public MyStyles()
    {
        InitializeComponent();
    }
  }
}
xmlns:resDictStyles="clr-namespace:MyNamespace"
...
<ContentView.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <resDictStyles:MyStyles />
    </ResourceDictionary.MergedDictionaries>
  </ResourceDictionary>
</ContentView.Resources>
...
<Label Style="{StaticResource LabelResDictStyle}" />
xmlns:resDictStyles="clr-namespace:MyNamespace"
...
<ContentPage.Resources>
  <ResourceDictionary>
    <ResourceDictionary.MergedDictionaries>
      <resDictStyles:MyStyles />
    </ResourceDictionary.MergedDictionaries>
    <Style x:Key="LabelPageStyle" TargetType="Label" BasedOn="{StaticResource LabelResDictStyle}">
      <Setter Property="FontSize" Value="20"></Setter>
    </Style>
  </ResourceDictionary>
</ContentPage.Resources>
...
<Label Style="{StaticResource LabelPageStyle}" />