Why are my values empty in object[] values when using IMultiValueConverter, but seems to have values when used without it in the View?

huangapple go评论136阅读模式
英文:

Why are my values empty in object[] values when using IMultiValueConverter, but seems to have values when used without it in the View?

问题

请帮助我理解这段代码。我在我的视图中有以下内容:

<Label 
    x:Name="communityAndUserLabel"
    Grid.Row="2"
    Grid.Column="1"
    FontAttributes="None"
    VerticalOptions="End">
    <Label.Text>
        <MultiBinding StringFormat="{}{0} • {1}">
            <Binding Path="CommunityName" />
            <Binding Path="Username" />
        </MultiBinding>
    </Label.Text>
    <Label.TextColor>
        <MultiBinding Converter="{StaticResource CommunityTextColorConverter}">
            <Binding Path="CommunityName" 
                Source="x:Reference communityAndUserLabel" />
            <Binding Path="Username" 
                Source="x:Reference communityAndUserLabel" />
        </MultiBinding>
    </Label.TextColor>
</Label>

当应用程序运行时,CommunityName 和 Username 以 Label.Text StringFormat 指定的格式显示,但是当满足条件时,颜色没有发生变化。我发现这是因为在开始时,object[] values 似乎没有将任何数据传递到 CommunityTextColorConvertor.cs 文件中,因此一切都被评估为 null/empty。

CommunityTextColorConverter.cs 文件如下:

using System.Globalization;

namespace Disc.Converters
{
    public class CommunityTextColorConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        { // Check if the values are valid if (values == null || values.Length != 2) return Colors.Black;

            // Get the community name and username from the values array
            string CommunityName = values[0] as string;

            // Check if the community name and username are not null or empty
            if (string.IsNullOrEmpty(CommunityName))
            {
                return Colors.PowderBlue; //default color when unset
            }

            // Define some colors for different communities
            Color red = Color.FromRgb(255, 0, 0);
            Color green = Color.FromRgb(0, 255, 0);
            Color blue = Color.FromRgb(0, 0, 255);

            // Return a different color based on the community name
            switch (CommunityName.ToLower())
            {
                case "nintendo":
                    return red;
                case "xbox":
                    return green;
                case "playstation":
                    return blue;
                case "pcgaming":
                    return Colors.Purple;
                case "news":
                    return Colors.Pink;
                default:
                    return Colors.PowderBlue;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            // Not implemented
            throw new NotImplementedException();
        }
    }
}

我尝试过的事情:

  • 在 Label.TextColor 元素中设置 Binding Path="Text"
  • 在 Label.TextColor 元素中设置 Binding Path="CommunityName"(在另一个元素中设置 Username)
  • 不更改任何内容再次运行它,希望它会神奇地工作
英文:

Please help me understand this. I have the following in my View:

<Label 
    x:Name="communityAndUserLabel"
    Grid.Row="2"
    Grid.Column="1"
    FontAttributes="None"
    VerticalOptions="End">
    <Label.Text>
        <MultiBinding StringFormat="{}{0} • {1}">
            <Binding Path="CommunityName" />
            <Binding Path="Username" />
        </MultiBinding>
    </Label.Text>
    <Label.TextColor>
        <MultiBinding Converter="{StaticResource CommunityTextColorConverter}">
            <Binding Path="CommunityName" 
                Source="x:Reference communityAndUserLabel" />
            <Binding Path="Username" 
                Source="x:Reference communityAndUserLabel" />
        </MultiBinding>
    </Label.TextColor>
</Label>

When the application runs, the CommunityName and Username appear formatted as they should as specified by Label.Text StringFormat; however, no color change is taking place when criteria is met. I've found that this is because object[] values doesn't seem to getting any data into the CommunityTextColorConvertor.cs file at the start, so everything evaluates as null/empty.

The CommunityTextColorConverter.cs:

using System.Globalization;

namespace Disc.Converters
{
    public class CommunityTextColorConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        { // Check if the values are valid if (values == null || values.Length != 2) return Colors.Black;

            // Get the community name and username from the values array
            string CommunityName = values[0] as string;

            // Check if the community name and username are not null or empty
            if (string.IsNullOrEmpty(CommunityName))
            {
                return Colors.PowderBlue; //default color when unset
            }

            // Define some colors for different communities
            Color red = Color.FromRgb(255, 0, 0);
            Color green = Color.FromRgb(0, 255, 0);
            Color blue = Color.FromRgb(0, 0, 255);

            // Return a different color based on the community name
            switch (CommunityName.ToLower())
            {
                case "nintendo":
                    return red;
                case "xbox":
                    return green;
                case "playstation":
                    return blue;
                case "pcgaming":
                    return Colors.Purple;
                case "news":
                    return Colors.Pink;
                default:
                    return Colors.PowderBlue;
            }
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            // Not implemented
            throw new NotImplementedException();
        }
    }
}

Thing I have tried:

  • setting Binding Path="Text" in the Label.TextColor elements
  • setting Binding Path="CommunityName" in the Label.TextColor element (and Username on the other)
  • running it again without changing anything at all hoping it will magically work this time

答案1

得分: 0

我能够获取到传入的值,这实际上是我的问题,所以我想我应该将“解决方案”发布为答案?Julian提到绑定源错误使我找到了正确的路径。虽然它还不像我尝试的那样完全工作(只能将整个字符串显示为单一颜色),但更新的(半)工作代码如下:

NameColorMultiConverter.cs

using System.Globalization;

namespace Disc.Converters
{
    public class NameColorMultiConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Console.WriteLine("CommunityName: " + values[0]);
            Console.WriteLine("Username: " + values[1]);
            // 检查输入值是否为字符串
            if (values[0] is not string community || values[1] is not string username)
                return Colors.Black;

            // 定义已知社区名称的数组
            string[] communities = new[] 
            { 
                "PlayStation", 
                "Xbox", 
                "PCGaming", 
                "Nintendo",
                "Discuit"
            };

            // 定义一个 switch 表达式将社区名称映射到颜色
            Color communityColor = community switch
            {
                "PlayStation" => Colors.Blue,
                "Xbox" => Colors.Green,
                "PCGaming" => Colors.Purple,
                "Nintendo" => Colors.Red,
                "Discuit" => Colors.Purple,
                // 需要时添加更多 case
                _ => Colors.Aqua // 默认情况
            };

            // 定义已知用户名的数组
            string[] usernames = new[]
            {
                "Previnder",
                "ReticentRobot",
                "TestAccountPlsIgnore",
                "RenegadeBAM",
                "gsurfer04"
            };

            // 定义一个 switch 表达式将用户名映射到颜色
            Color usernameColor = username switch
            {
                "Previnder" => Colors.Red,
                "ReticentRobot" => Colors.Orange,
                "TestAccountPlsIgnore" => Colors.Yellow,
                "RenegadeBAM" => Colors.Green,
                "gsurfer04" => Colors.Blue,
                // 需要时添加更多 case
                _ => Colors.Pink // 默认情况
            };

            // 根据参数值返回社区名称或用户名的颜色
            return parameter switch
            {
                "community" => communityColor,
                "username" => usernameColor,
                _ => Colors.AntiqueWhite // 默认情况
            };
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            // 此转换器不支持转换回来
            throw new NotImplementedException();
        }
    }
}

伴随的 XAML

<Label 
    x:Name="communityAndUserLabel"
    Grid.Row="2"
    Grid.Column="1"
    FontAttributes="None"
    VerticalOptions="End">
    <Label.Text>
        <MultiBinding StringFormat="{}{0} • {1}" Mode="TwoWay">
            <Binding Path="CommunityName" />
            <Binding Path="Username" />
        </MultiBinding>
    </Label.Text>
    <Label.TextColor>
        <MultiBinding Converter="{StaticResource nameColorMulti}" ConverterParameter="community">
            <Binding Path="CommunityName" />
            <Binding Path="Username" />
        </MultiBinding>
    </Label.TextColor>
</Label>
英文:

I was able to get the values pulling in, which technically was my question - so I guess I should post the 'solution' as the answer? Julian's mention of the binding source being wrong set me on the right path. It's still not working quite like I'm attempting to do (Can only get the whole string displaying as a single color), but the updated (semi) working code is here:

NameColorMultiConverter.cs

using System.Globalization;

namespace Disc.Converters
{
    public class NameColorMultiConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            Console.WriteLine(&quot;CommunityName: &quot; + values[0]);
            Console.WriteLine(&quot;Username: &quot; + values[1]);
            // Check if the input values are strings
            if (values[0] is not string community || values[1] is not string username)
                return Colors.Black;

            // Define an array of known community names
            string[] communities = new[] 
            { 
                &quot;PlayStation&quot;, 
                &quot;Xbox&quot;, 
                &quot;PCGaming&quot;, 
                &quot;Nintendo&quot;,
                &quot;Discuit&quot;
            };

            // Define a switch expression to map community names to colors
            Color communityColor = community switch
            {
                &quot;PlayStation&quot; =&gt; Colors.Blue,
                &quot;Xbox&quot; =&gt; Colors.Green,
                &quot;PCGaming&quot; =&gt; Colors.Purple,
                &quot;Nintendo&quot; =&gt; Colors.Red,
                &quot;Discuit&quot; =&gt; Colors.Purple,
                // Add more cases as needed
                _ =&gt; Colors.Aqua // Default case
            };

            // Define an array of known usernames
            string[] usernames = new[]
            {
                &quot;Previnder&quot;,
                &quot;ReticentRobot&quot;,
                &quot;TestAccountPlsIgnore&quot;,
                &quot;RenegadeBAM&quot;,
                &quot;gsurfer04&quot;
            };

            // Define a switch expression to map usernames to colors
            Color usernameColor = username switch
            {
                &quot;Previnder&quot; =&gt; Colors.Red,
                &quot;ReticentRobot&quot; =&gt; Colors.Orange,
                &quot;TestAccountPlsIgnore&quot; =&gt; Colors.Yellow,
                &quot;RenegadeBAM&quot; =&gt; Colors.Green,
                &quot;gsurfer04&quot; =&gt; Colors.Blue,
                // Add more cases as needed
                _ =&gt; Colors.Pink // Default case
            };

            // Return the color for the community name or the username based on the parameter value
            return parameter switch
            {
                &quot;community&quot; =&gt; communityColor,
                &quot;username&quot; =&gt; usernameColor,
                _ =&gt; Colors.AntiqueWhite // Default case
            };
        }

        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            // This converter does not support converting back
            throw new NotImplementedException();
        }
    }
}

Accompanying XAML

&lt;Label 
    x:Name=&quot;communityAndUserLabel&quot;
    Grid.Row=&quot;2&quot;
    Grid.Column=&quot;1&quot;
    FontAttributes=&quot;None&quot;
    VerticalOptions=&quot;End&quot;&gt;
    &lt;Label.Text&gt;
        &lt;MultiBinding StringFormat=&quot;{}{0} • {1}&quot; Mode=&quot;TwoWay&quot;&gt;
            &lt;Binding Path=&quot;CommunityName&quot; /&gt;
            &lt;Binding Path=&quot;Username&quot; /&gt;
        &lt;/MultiBinding&gt;
    &lt;/Label.Text&gt;
    &lt;Label.TextColor&gt;
        &lt;MultiBinding Converter=&quot;{StaticResource nameColorMulti}&quot; ConverterParameter=&quot;community&quot;&gt;
            &lt;Binding Path=&quot;CommunityName&quot; /&gt;
            &lt;Binding Path=&quot;Username&quot; /&gt;
        &lt;/MultiBinding&gt;
    &lt;/Label.TextColor&gt;
&lt;/Label&gt;

huangapple
  • 本文由 发表于 2023年8月8日 21:57:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/76860258.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定