集合更新后转换器未触发
Converter not firing after collection update
我 运行 遇到了转换器问题...一旦绑定集合更新,它们就不会触发,尽管它们在集合首次填充时触发。每当集合发生变化时,我想让它们开火。
到目前为止,我已经构建了一个简单的转换器:
public class TableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
VM.Measurement t = ((VM.Measurement)((TextBlock)value).DataContext);
if (t.Delta != null)
{
if (Math.Abs((double)t.Delta) < t.Tol)
return "Green";
else
return "Red";
}
else
return "Red";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
链接到样式
<conv:TableConverter x:Key="styleConvStr"/>
<Style x:Key="CellStyleSelectorTol" TargetType="syncfusion:GridCell">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content, Converter={StaticResource styleConvStr}}" />
</Style>
这个DataGrid中用到的
<syncfusion:SfDataGrid x:Name="CheckGrid" BorderBrush="White" Grid.Row="1" Grid.Column="1" AllowEditing="True" ItemsSource="{Binding ChecksList, Mode=TwoWay}" Background="White" SnapsToDevicePixels="False"
ColumnSizer="None" AllowResizingColumns="False" AllowTriStateSorting="True" AllowDraggingColumns="False" CurrentCellEndEdit="CheckGrid_CurrentCellEndEdit" AutoGenerateColumns="False"
NavigationMode="Cell" HeaderRowHeight="30" RowHeight="21" GridPasteOption="None" Margin="20 10 10 10" AllowGrouping="True" SelectedItem="{Binding SelectedLine, Mode=TwoWay}"
SelectionUnit="Row" SelectionMode="Single" RowSelectionBrush="#CBACCB" VirtualizingPanel.IsVirtualizing="True" Visibility="Visible">
<syncfusion:GridTextColumn Width="100" ColumnSizer="SizeToCells" AllowEditing="True" MappingName="Measured" CellStyle="{StaticResource CellStyleSelectorTol}" HeaderText="Measured" TextAlignment="Center" AllowFiltering="False" FilterBehavior="StringTyped"/>
VM 包含一个 Observable 集合,它实现 NotifyPropertyChanged 一直到测量 Class。这些属性很好地启动,所以它不是一个有约束力的问题。
private ObservableCollection<Measurement> _checkList = new ObservableCollection<Measurement>();
public ObservableCollection<Measurement> ChecksList
{
get
{
return _checkList;
}
set
{
_checkList = value;
NotifyPropertyChanged();
}
}
如有任何帮助,我们将不胜感激。
谢谢
编辑:
这是更新集合的代码。很抱歉它很乱。 Lineitem 是为其更新 Measured 和 Delta 的选定行。一旦修改,这些就会正确显示在网格中。
public void NewMeasurement(VM.Measurement measurementShell)
{
using (VMEntity DB = new VMEntity())
{
var Check = CheckSets.Where(x => x.ID == SelectedLine.ID).First();
if (Check.Measurement == null)
{
Check.Measurement = measurementShell.Index;
var Lineitem = ChecksList.Where(x => x.ID == SelectedLine.ID).First();
var measurement = DB.Measurements.Where(x => x.Index == Check.Measurement).First();
Lineitem.Measured = (double)measurement.measurement1;
Lineitem.Delta = Lineitem.Measured - Lineitem.Target;
好的,看起来问题是您正在更改 的 单元格内容项的属性(LineItem
,在 NewMeasurement()
方法中),但它仍然是同一个对象,所以单元格的内容没有改变。单元格的 Content
是绑定的来源。如果那没有改变,绑定将不会唤醒并更新目标。你正在提高 PropertyChanged
,但这个特定的绑定无法知道你想让它为 those 监听 this 对象属性变化。足够简单的修复:我们将开始准确地告诉它要听什么。
幸运的是,解决方案意味着简化您的一些代码。将 UI 控件传递给值转换器是奇异的,没有必要。
您在转换器中关心的是Measurement.Delta
和Measurement.Tol
。当任何一个改变时,绑定应该更新它的目标。你不想以一种聪明的方式做到这一点。您只需要每个 Binding
。那是 Binding
的工作。
所以告诉 Binding
你关心那些属性,并重写转换器以接受它们作为参数。
<Style x:Key="CellStyleSelectorTol" TargetType="syncfusion:GridCell">
<Setter
Property="Background"
>
<Setter.Value>
<MultiBinding Converter="{StaticResource styleConvStr}">
<Binding Path="Delta" />
<Binding Path="Tol" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
转换器:
public class TableConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// I'm inferring that Measurement.Delta is Nullable<double>; if that's
// not the case, change accordingly. Is it Object instead?
double? delta = (double?)values[0];
double tol = (double)values[1];
if (delta.HasValue && Math.Abs(delta.Value) < tol)
{
return "Green";
}
return "Red";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
我 运行 遇到了转换器问题...一旦绑定集合更新,它们就不会触发,尽管它们在集合首次填充时触发。每当集合发生变化时,我想让它们开火。
到目前为止,我已经构建了一个简单的转换器:
public class TableConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
VM.Measurement t = ((VM.Measurement)((TextBlock)value).DataContext);
if (t.Delta != null)
{
if (Math.Abs((double)t.Delta) < t.Tol)
return "Green";
else
return "Red";
}
else
return "Red";
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
链接到样式
<conv:TableConverter x:Key="styleConvStr"/>
<Style x:Key="CellStyleSelectorTol" TargetType="syncfusion:GridCell">
<Setter Property="Background" Value="{Binding RelativeSource={RelativeSource Self}, Path=Content, Converter={StaticResource styleConvStr}}" />
</Style>
这个DataGrid中用到的
<syncfusion:SfDataGrid x:Name="CheckGrid" BorderBrush="White" Grid.Row="1" Grid.Column="1" AllowEditing="True" ItemsSource="{Binding ChecksList, Mode=TwoWay}" Background="White" SnapsToDevicePixels="False"
ColumnSizer="None" AllowResizingColumns="False" AllowTriStateSorting="True" AllowDraggingColumns="False" CurrentCellEndEdit="CheckGrid_CurrentCellEndEdit" AutoGenerateColumns="False"
NavigationMode="Cell" HeaderRowHeight="30" RowHeight="21" GridPasteOption="None" Margin="20 10 10 10" AllowGrouping="True" SelectedItem="{Binding SelectedLine, Mode=TwoWay}"
SelectionUnit="Row" SelectionMode="Single" RowSelectionBrush="#CBACCB" VirtualizingPanel.IsVirtualizing="True" Visibility="Visible">
<syncfusion:GridTextColumn Width="100" ColumnSizer="SizeToCells" AllowEditing="True" MappingName="Measured" CellStyle="{StaticResource CellStyleSelectorTol}" HeaderText="Measured" TextAlignment="Center" AllowFiltering="False" FilterBehavior="StringTyped"/>
VM 包含一个 Observable 集合,它实现 NotifyPropertyChanged 一直到测量 Class。这些属性很好地启动,所以它不是一个有约束力的问题。
private ObservableCollection<Measurement> _checkList = new ObservableCollection<Measurement>();
public ObservableCollection<Measurement> ChecksList
{
get
{
return _checkList;
}
set
{
_checkList = value;
NotifyPropertyChanged();
}
}
如有任何帮助,我们将不胜感激。
谢谢
编辑: 这是更新集合的代码。很抱歉它很乱。 Lineitem 是为其更新 Measured 和 Delta 的选定行。一旦修改,这些就会正确显示在网格中。
public void NewMeasurement(VM.Measurement measurementShell)
{
using (VMEntity DB = new VMEntity())
{
var Check = CheckSets.Where(x => x.ID == SelectedLine.ID).First();
if (Check.Measurement == null)
{
Check.Measurement = measurementShell.Index;
var Lineitem = ChecksList.Where(x => x.ID == SelectedLine.ID).First();
var measurement = DB.Measurements.Where(x => x.Index == Check.Measurement).First();
Lineitem.Measured = (double)measurement.measurement1;
Lineitem.Delta = Lineitem.Measured - Lineitem.Target;
好的,看起来问题是您正在更改 的 单元格内容项的属性(LineItem
,在 NewMeasurement()
方法中),但它仍然是同一个对象,所以单元格的内容没有改变。单元格的 Content
是绑定的来源。如果那没有改变,绑定将不会唤醒并更新目标。你正在提高 PropertyChanged
,但这个特定的绑定无法知道你想让它为 those 监听 this 对象属性变化。足够简单的修复:我们将开始准确地告诉它要听什么。
幸运的是,解决方案意味着简化您的一些代码。将 UI 控件传递给值转换器是奇异的,没有必要。
您在转换器中关心的是Measurement.Delta
和Measurement.Tol
。当任何一个改变时,绑定应该更新它的目标。你不想以一种聪明的方式做到这一点。您只需要每个 Binding
。那是 Binding
的工作。
所以告诉 Binding
你关心那些属性,并重写转换器以接受它们作为参数。
<Style x:Key="CellStyleSelectorTol" TargetType="syncfusion:GridCell">
<Setter
Property="Background"
>
<Setter.Value>
<MultiBinding Converter="{StaticResource styleConvStr}">
<Binding Path="Delta" />
<Binding Path="Tol" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style>
转换器:
public class TableConverter : IMultiValueConverter
{
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
// I'm inferring that Measurement.Delta is Nullable<double>; if that's
// not the case, change accordingly. Is it Object instead?
double? delta = (double?)values[0];
double tol = (double)values[1];
if (delta.HasValue && Math.Abs(delta.Value) < tol)
{
return "Green";
}
return "Red";
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}