我有一個DataGrid. 中有 12 列DataGrid。這些列中的每一列都代表byte0-255 之間的值。我想根據用戶輸入的范圍對它們進行著色。
我不知道如何根據用戶輸入更改這些值。用戶可以為每一列指定不同的范圍。下面是我手動實作的應用程式。如何將此應用程式系結到用戶登錄。
轉換器
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();
}
}
xml
<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 中擁擠。
例如,用戶想要Blue0-100Red之間、100-150Green之間、150-255之間。
uj5u.com熱心網友回復:
我不知道如何根據用戶輸入更改這些值。用戶可以為每一列指定不同的范圍。
如果用戶可以指定范圍,例如通過Sliders 或TextBoxes,則需要系結這些值以對更改做出反應。讓我們假設這些值映射到的畫筆不需要系結(還)。AnIValueConverter只能系結一個值。您可以改為創建一個IMultiValueConverter,顧名思義,它可以系結多個值。具體轉換器的外觀有多種選擇,具體取決于您的視圖、視圖模型和其他要求。
下面是一個IMultiValueConverter允許系結多個byte屬性的示例,其中第一個是data要比較的原始值,其余表示每個范圍的邊界。Brush這些范圍的es 作為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://www.uj5u.com/yidong/318306.html
