我有一个DataGrid。DataGrid中有12列。这些列中的每一列表示0-255之间的byte值。我想根据用户输入的范围对它们进行着色。
我不知道如何根据用户输入更改这些值。用户可以为每一列指定不同的范围。下面是我手动实现的应用程序。如何将此应用程序绑定到用户登录。
变换器
public class DataGridColorConverter : IValueConverter
{
public object Convert(
object value, Type targetType,
object parameter, CultureInfo culture)
{
byte data = (byte)value;
if (data <= 30)
return 0;
else if (data <= 60)
return 1;
else if (data <= 90)
return 2;
else
return 3;
}
public object ConvertBack(
object value, Type targetType,
object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}Xaml
<UserControl.Resources>
<my:DataGridColorConverter x:Key="DGCConverter"/>
</UserControl.Resources>
<DataGrid Name="MyDataGrid"
Grid.Row="1"
AutoGenerateColumns="False"
ItemsSource="{Binding JobsCollectionView , IsAsync=True}"
VirtualizingStackPanel.VirtualizationMode="Recycling"
IsReadOnly="True"
Height="480">
<DataGrid.Columns>
<DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
<DataGridTextColumn Header="RTR" Binding="{Binding RTR}"/>
<DataGridTextColumn Header="IDE" Binding="{Binding IDE}"/>
<DataGridTextColumn Header="DLC" Binding="{Binding DLC}"/>
<DataGridTextColumn Header="BYTE-0" Binding="{Binding Byte0}"/>
<DataGridTextColumn Header="BYTE-1" Binding="{Binding Byte1}"/>
<DataGridTextColumn Header="BYTE-2" Binding="{Binding Byte2}"/>
<DataGridTextColumn Header="BYTE-3" Binding="{Binding Byte3}"/>
<DataGridTextColumn Header="BYTE-4" Binding="{Binding Byte4}"/>
<DataGridTextColumn Header="BYTE-5" Binding="{Binding Byte5}"/>
<DataGridTextColumn Header="BYTE-6" Binding="{Binding Byte6}"/>
<DataGridTextColumn Header="BYTE-7" Binding="{Binding Byte7}">
<DataGridTextColumn.ElementStyle>
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground" Value="Green" />
<Style.Triggers>
<DataTrigger Binding="{Binding Byte7,Converter={StaticResource DGCConverter}}" Value="1">
<Setter Property="Foreground" Value="Yellow" />
</DataTrigger>
<DataTrigger Binding="{Binding Byte7,Converter={StaticResource DGCConverter}}" Value="2">
<Setter Property="Foreground" Value="Orange" />
</DataTrigger>
<DataTrigger Binding="{Binding Byte7,Converter={StaticResource DGCConverter}}" Value="3">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
</Style>
</DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Header="TIME" Binding="{Binding Time, StringFormat=\{0:dd.MM.yy HH:mm:ss\}}"/>
</DataGrid.Columns>
</DataGrid>注意事项:我正在使用MVVM。
备注2:我没有共享用户可以输入值范围的字段,以便它在XAML中不拥挤。
例如,用户希望Blue在0-100之间,Red在100-150之间,Green在150-255之间.
发布于 2021-10-15 10:56:19
--我不知道如何根据用户输入更改这些值。用户可以为每一列指定不同的范围。
如果用户可以指定范围,例如通过Sliders或TextBoxes,则需要绑定这些值以对更改作出反应。让我们假设这些值映射的画笔不需要绑定(目前)。IValueConverter只能绑定单个值。您可以创建一个IMultiValueConverter,它可以绑定多个值,如其名称所示。具体转换器的外观有多个选项,取决于您的视图、视图模型和其他需求。
下面是一个IMultiValueConverter示例,它允许绑定多个byte属性,其中第一个属性是要比较的原始data值,其余属性表示每个范围的边界。这些范围的Brushes作为parameter (集合)传递,不可绑定。如果您希望它们也是可绑定的,那么它们也将通过values数组传递。此转换器假定所有值都是bytes,而parameter是Brushes的集合。此外,必须有不同的范围边界(没有重复的)和相同数量的Brushes (可以是重复的),否则就没有1:1的映射(抛出异常)。如果没有绑定值或可能的映射,则不会返回画笔。
public class DataGridColorConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values == null)
return Binding.DoNothing;
var byteValues = values.Cast<byte>().ToList();
var brushes = ((IEnumerable)parameter).Cast<Brush>().ToList();
var data = byteValues[0];
var bounds = byteValues.Skip(1).Distinct().ToList();
if (bounds.Count != brushes.Count)
throw new ArgumentException("The number of distinct stops must be equal to the number of stop brushes.");
foreach (var (boundary, brush) in bounds.Zip(brushes))
{
if (data <= boundary)
return brush;
}
return Binding.DoNothing;
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}在XAML中,可以使用新的转换器使用MultiBinding来调整样式。
<Style TargetType="{x:Type TextBlock}">
<Setter Property="Foreground">
<Setter.Value>
<MultiBinding Converter="{StaticResource DataGridColorConverter}">
<MultiBinding.Bindings>
<!-- ...binds the current data context, your BYTE 7. -->
<Binding/>
<!-- ...these bindings may vary depending on the source for binding, view model, text block, ... -->
<Binding Path="MyBlueRangeEndProperty"/>
<Binding Path="MyRedRangeEndProperty"/>
<Binding Path="MyGreenRangeEndProperty"/>
</MultiBinding.Bindings>
<MultiBinding.ConverterParameter>
<!-- ...this array could also be shared (moved to resource and refernce via {StaticResource ...}). -->
<x:Array Type="{x:Type Brush}">
<SolidColorBrush Color="Blue"/>
<SolidColorBrush Color="Red"/>
<SolidColorBrush Color="Green"/>
</x:Array>
</MultiBinding.ConverterParameter>
</MultiBinding>
</Setter.Value>
</Setter>
</Style>如上文所述,实现这一目标有许多备选方案。对于您的用例来说,这应该足够了,如果颜色数组对于所有列都是相同的,或者单独定义每个列,那么您甚至可以共享颜色数组。
更新有关使用Zip编译错误的注释。此扩展方法并不适用于所有目标框架。这同样适用于C#语言版本和元组解构。但是,在这些情况下,您可以使用一个简单的for循环。
for (var i = 0; i < bounds.Count; i++)
{
if (data <= bounds[i])
return brushes[i];
}https://stackoverflow.com/questions/69580946
复制相似问题