英文:
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("CommunityName: " + values[0]);
Console.WriteLine("Username: " + 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[]
{
"PlayStation",
"Xbox",
"PCGaming",
"Nintendo",
"Discuit"
};
// Define a switch expression to map community names to colors
Color communityColor = community switch
{
"PlayStation" => Colors.Blue,
"Xbox" => Colors.Green,
"PCGaming" => Colors.Purple,
"Nintendo" => Colors.Red,
"Discuit" => Colors.Purple,
// Add more cases as needed
_ => Colors.Aqua // Default case
};
// Define an array of known usernames
string[] usernames = new[]
{
"Previnder",
"ReticentRobot",
"TestAccountPlsIgnore",
"RenegadeBAM",
"gsurfer04"
};
// Define a switch expression to map usernames to colors
Color usernameColor = username switch
{
"Previnder" => Colors.Red,
"ReticentRobot" => Colors.Orange,
"TestAccountPlsIgnore" => Colors.Yellow,
"RenegadeBAM" => Colors.Green,
"gsurfer04" => Colors.Blue,
// Add more cases as needed
_ => Colors.Pink // Default case
};
// Return the color for the community name or the username based on the parameter value
return parameter switch
{
"community" => communityColor,
"username" => usernameColor,
_ => 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
<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>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论