如何在XAML中直接用IValueConverter绑定ResourceDictionary的值?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在XAML中直接用IValueConverter绑定ResourceDictionary的值?相关的知识,希望对你有一定的参考价值。

我想在ResourceDictionary里面绑定一个值,这是一个主题。

我按照一些教程在 https:/docs.microsoft.comen-usxamarinxamarin-formsuser-interfacethemingtheming。

下面是名为Black.xaml的ResourceDictionary的代码。

<?xml version="1.0" encoding="utf-8"?>
<ResourceDictionary xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Test.Themes.Black">
    <Color x:Key="PrimaryBackground" x:FactoryMethod="FromHex">
        <x:Arguments>
            <x:String>#101010</x:String>
        </x:Arguments>
    </Color>    
</ResourceDictionary>

这里是App. xaml的代码:

<?xml version="1.0" encoding="utf-8" ?>
<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="Test.App">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Themes/Black.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

这是ContentView的代码

<?xml version="1.0" encoding="UTF-8"?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms" 
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:local="clr-namespace:Test.Views"
             xmlns:VM="clr-namespace:Test.ViewModels"             
             mc:Ignorable="d"             
             x:Class="Test.Views.MainView">
    <ContentView.BindingContext>
        <VM:MainViewVM></VM:MainViewVM>
    </ContentView.BindingContext>    
    <ContentView.Content>
        <Grid BackgroundColor="">            
        </Grid>
    </ContentView.Content>
</ContentView>

现在我想把上面Grid的BackgroundColor属性绑定到值上。PrimaryBackground 的资源字典。

怎样才能实现呢?谢谢。

答案

只要使用 DynamicResource 来设置 BackgroundColor 如以下代码

<Grid BackgroundColor="{DynamicResource PrimaryBackground}">
            <Label Text="Face-Palm Monkey"
                   VerticalOptions="Center"
                   Margin="15"/>

</Grid>

这是运行中的Sceenshot。

enter image description here

我建议你把 ResourceDictionary 直接在 App.xaml 如以下格式。

<Application xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             mc:Ignorable="d"
             x:Class="MVVMWebView.App">
    <Application.Resources>
        <ResourceDictionary>
            <Color x:Key="PrimaryBackground" x:FactoryMethod="FromHex">
                <x:Arguments>
                    <x:String>#101010</x:String>
                </x:Arguments>
            </Color>

        </ResourceDictionary>
    </Application.Resources>
</Application>

如果你想使用 IValueConverter ,只需加上 ConverterContentPage.Resources 喜欢跟着代码走。IValueConverter 用过的 Converter 标签,你只需使用 StaticResource它不与 DynamicResource

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:DataBindingDemos"
             x:Class="DataBindingDemos.EnableButtonsPage"
             Title="Enable Buttons">
    <ContentPage.Resources>
        <ResourceDictionary>
            <local:IntToBoolConverter x:Key="intToBool" />
        </ResourceDictionary>
    </ContentPage.Resources>

    <StackLayout Padding="10, 0">


        <Button Text="Search"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                IsEnabled="{Binding Source={x:Reference entry1},
                                    Path=Text.Length,
                                    Converter={StaticResource intToBool}}" />
     </StackLayout>
   </ContentPage>

更新

我按你的需求做转换。我用的是 Button 来转换白天和夜晚。这里是正在运行的GIF。

enter image description here

 <ContentPage.Resources>
        <ResourceDictionary>
            <controls:ColorBoolConverter x:Key="intToBool" />
        </ResourceDictionary>
    </ContentPage.Resources>
    <StackLayout>

        <Button Text="Submit"
                HorizontalOptions="Center"
                VerticalOptions="CenterAndExpand"
                Command="{Binding ChangeCommand}"
                />

        <!-- Place new controls here -->
        <Grid BackgroundColor="{Binding IsDark, Converter={StaticResource intToBool}}">
            <Label Text="Face-Palm Monkey"
                       VerticalOptions="Center"
                       Margin="15"
                        />

        </Grid>
    </StackLayout>

这里是关于布局的背景代码。

  public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            this.BindingContext = new MyViewModel();
        }
    }

这里是Convertor代码。

    public class ColorBoolConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value is bool)
            {
                if ((Boolean)value)
                    return Color.FromHex("#101010");
                else
                    return Color.White;
            }
            return Color.White;
        }

        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

这里是测试 MyViewModel.cs

    public class MyViewModel: INotifyPropertyChanged
    {
        public ICommand ChangeCommand { protected set; get; }
        bool _isDark = false;
        public bool IsDark
        {
            get
            {
                return _isDark;
            }

            set
            {
                if (_isDark != value)
                {
                    _isDark = value;
                    OnPropertyChanged("IsDark");

                }
            }

        }




        public MyViewModel()
        {
            ChangeCommand =  new Command(() =>
            {

                IsDark = !IsDark;


            });
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

以上是关于如何在XAML中直接用IValueConverter绑定ResourceDictionary的值?的主要内容,如果未能解决你的问题,请参考以下文章

WPF中XAML的触发器的属性,事件 都有那些?以及如何寻找

Xamarin表单ListView ItemTapped / ItemSelected在XAML上绑定命令

WPF中XAML的触发器的属性,事件 都有那些?以及如何寻找

wpf 多语言对应 切换了 dll后 如何刷新窗体(window)

C# WPF中xaml怎么调用.cs中的数据?反过来怎么调用?

从 XAML 中的 *.resx 文件中获取值