【问题标题】:How can I binding a value of the ResourceDictionary with IValueConverter in XAML directly?如何直接在 XAML 中将 ResourceDictionary 的值与 IValueConverter 绑定?
【发布时间】:2020-05-14 20:30:27
【问题描述】:

我想在作为主题的 ResourceDictionary 中绑定一个值。

我在https://docs.microsoft.com/en-us/xamarin/xamarin-forms/user-interface/theming/theming 中学习了一些教程

这是名为 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 属性绑定到 ResourceDictionary 的值 PrimaryBackground

我怎样才能实现它?谢谢。

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    只需使用DynamicResource 设置BackgroundColor,如下代码所示

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

    这是运行截图。

    我建议您将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,只需在ContentPage.Resources 中添加Converter,就像跟随代码一样。 IValueConverterConverter标签,你用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。

     <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();
            }
        }
    

    这是转换器代码。

        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));
            }
        }
    }
    

    【讨论】:

    • 还有,如果需要使用IValueConverter怎么办?
    • Li IValueConverter 的代码与我的项目不同。恐怕我并不完全明白它的意思。我尝试修改如下代码:{Binding Source={x:Reference Test},Path=PrimaryBackground,Converter={StaticResource intToBool}} 虽然它不起作用但报告错误。
    • 您想根据某些条件转换您的背景吗?比如数值超过50,背景色是黑色,如果数值自爆50,背景色是红色?你能分享你的转换代码吗?
    • 如果使用ResourceDictionary设置颜色,是静态样式,如果使用Converter,是动态转换,它们是不同的。
    • 是的,有两种不同类型的主题,一种是浅色的,另一种是深色的。我在资源字典中设置了一个名为 IsDark 的布尔值。当 IsDark 为 true 时,它​​将显示深色主题的图像。当 IsDark 设置为 false 时,它​​将显示浅色主题的图像。所以我必须获取 IsDark 的值并使用 IValueConverter 设置图像的来源。
    猜你喜欢
    • 2013-01-31
    • 2013-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 2013-05-17
    • 1970-01-01
    相关资源
    最近更新 更多