Как определить константу в C# и использовать ее в XAML? - PullRequest
4 голосов
/ 19 марта 2020

Я стараюсь определять константы для строковых значений всякий раз, когда это необходимо, чтобы не закапывать "волшебные c строки" в коде. Недавно я обнаружил, что мне нужно определить пользовательскую строку формата для конвертера, поэтому я определил public const string MyFormat = "a"; в конвертере. При использовании конвертера мне нужно передать «а» как ConverterParameter, но вместо ввода ConverterParameter=a я бы хотел сослаться на именованную константу.

<TextBlock Text="{x:Bind SomeProperty, Converter={StaticResource MyConverter}, ConverterParameter=???}" />

Я пробовал ConverterParameter=local:MyConverter.MyFormat, но он просто передает строку "local: MyConverter.MyFormat", а не "a".

Я пробовал ConverterParameter={x:Bind local:MyConverter.MyFormat}, но я получаю ошибку Nested x:Bind expressions are not supported.

Я попробовал ConverterParameter={StaticResource MyFormat} и добавил его в качестве ресурса, но это только перемещает проблему и вводит новую проблему:

  1. Я также не знаю, как ссылаться на константу в ресурсах , Я могу добавить <x:String x:Key="MyFormat">a</x:String>, но тогда я определил константу в двух разных местах, и если она изменится, я должен запомнить, чтобы обновить ее в двух разных местах.
  2. Даже если я сделаю это, строка будет не передан в качестве параметра, как ожидалось. Параметр равен нулю.

Есть ли способ сослаться на именованную константу в XAML? (Примечание: это UWP, а не WPF.)

Вот простое замечание:

MainPage.xaml

<Page
    x:Class="XamlConstantReference.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:local="using:XamlConstantReference"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
    mc:Ignorable="d">
    <Page.Resources>
        <local:MyConverter x:Key="MyConverter" />
        <!--  How do I refer to MyConverter.MyFormat rather than defining it a second time?  -->
        <x:String x:Key="MyFormat">a</x:String>
    </Page.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <!--  How do I refer to MyConverter.MyFormat rather than passing in ConverterParameter=a?  -->
        <TextBlock Grid.Row="0" Text="{x:Bind SomeProperty, Converter={StaticResource MyConverter}, ConverterParameter=a}" />
        <TextBlock Grid.Row="1" Text="{x:Bind SomeProperty, Converter={StaticResource MyConverter}, ConverterParameter=local:MyConverter.MyFormat}" />
        <!-- <TextBlock Grid.Row="2" Text="{x:Bind SomeProperty, Converter={StaticResource MyConverter}, ConverterParameter={x:Bind local:MyConverter.MyFormat}}" /> -->
        <TextBlock Grid.Row="3" Text="{x:Bind SomeProperty, Converter={StaticResource MyConverter}, ConverterParameter={StaticResource MyFormat}}" />
    </Grid>
</Page>

MainPage.xaml. cs

using System.ComponentModel;
using Windows.UI.Xaml.Controls;

namespace XamlConstantReference
{
    public sealed partial class MainPage : Page, INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private string _someProperty = "Hello World!";

        public string SomeProperty
        {
            get => _someProperty;
            set
            {
                if (_someProperty != value)
                {
                    _someProperty = value;
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(SomeProperty)));
                }
            }
        }

        public MainPage()
        {
            InitializeComponent();
        }
    }
}

MyConverter.cs

using System;
using Windows.UI.Xaml.Data;

namespace XamlConstantReference
{
    public class MyConverter : IValueConverter
    {
        public const string MyFormat = "a";

        public object Convert(object value, Type targetType, object parameter, string language)
        {
            if (parameter == null)
            {
                return $"Fail. Formatted '{value}' with null parameter.";
            }
            else if (parameter is string parameterString)
            {
                switch (parameterString)
                {
                    case MyFormat:
                        return $"Success! Formatted '{value}' with parameter '{parameterString}'.";

                    default:
                        return $"Fail. Formatted '{value}' with parameter '{parameterString}'.";
                }
            }

            throw new ArgumentException();
        }

        public object ConvertBack(object value, Type targetType, object parameter, string language)
        {
            throw new NotImplementedException();
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...