I am trying to create a DataGrid with two text columns and a template column as follows:
<UserControl
...
Name="TcpNtcpSliders"
...>
<DataGrid Name="MinTcpDataGrid" AutoGenerateColumns="False" Margin="2" Grid.Row="0"
ItemsSource="{Binding MinTcpRows, ElementName=TcpNtcpSliders, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<DataGrid.Columns>
<DataGridTextColumn Header="Structure ID" IsReadOnly="True" Width="Auto"
Binding="{Binding StructureId, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Min. TCP" IsReadOnly="True" Width="Auto" x:Name="MinTcpTextColumn"
Binding="{Binding MinTcpValue, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTemplateColumn Header="Set Min. Tcp" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Slider Minimum="0" Maximum="1"
Value="{Binding MinTcpValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</UserControl>
In the code behind I have
internal ObservableCollection<MinTcpRow> MinTcpRows
{
get { return (ObservableCollection<MinTcpRow>)GetValue(MinTcpRowsProperty); }
set { SetValue(MinTcpRowsProperty, value); }
}
internal static readonly DependencyProperty MinTcpRowsProperty =
DependencyProperty.Register("MinTcpRows", typeof(ObservableCollection<MinTcpRow>),
typeof(RtpOptimizationTcpNtcpSliders),
new PropertyMetadata(new ObservableCollection<MinTcpRow>(), MinTcpRowsPropertyChangedCallback));
private static void MinTcpRowsPropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var control = (RtpOptimizationTcpNtcpSliders)d;
control.MinTcpRows = (ObservableCollection<MinTcpRow>)e.NewValue;
control.CreateTcpNtcpLimits();
}
and the MinTcpRow
class is defined like:
public class MinTcpRow
{
public string StructureId { get; }
public double MinTcpValue { get; set; }
public MinTcpRow(string structureId, double minTcpValue)
{
if (minTcpValue < 0 || minTcpValue > 1)
throw new ArgumentOutOfRangeException($"{nameof(minTcpValue)} must " +
$"be in range [0, 1], but was {minTcpValue}.");
StructureId = structureId ?? throw new ArgumentNullException(nameof(structureId));
MinTcpValue = minTcpValue;
}
}
Everything works as expected, except for the Slider value binding. I says cannot resolve symbol 'MinTcpValue'
. How can I bind the slider's value correctly?
In order to see what happens I put a simplified version together.
In my mainwindow I have a datagrid:
<DataGrid Name="MinTcpDataGrid" AutoGenerateColumns="False"
ItemsSource="{Binding Rows}">
<DataGrid.Columns>
<DataGridTextColumn Header="Structure ID" IsReadOnly="True" Width="Auto"
Binding="{Binding StructureId, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}" />
<DataGridTextColumn Header="Min. TCP" IsReadOnly="True" Width="Auto" x:Name="MinTcpTextColumn"
Binding="{Binding MinTcpValue, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}"/>
<DataGridTemplateColumn Header="Set Min. Tcp" Width="*">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Slider Minimum="0" Maximum="1"
Value="{Binding MinTcpValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
MainWindowViewModel will supply my Rows collection:
public partial class MainWindowViewModel : ObservableObject
{
[ObservableProperty]
private ObservableCollection<MinTcpRow> rows = new ObservableCollection<MinTcpRow>();
public MainWindowViewModel()
{
rows.Add(new MinTcpRow ("A",0.1));
rows.Add(new MinTcpRow("B", 0.5));
rows.Add(new MinTcpRow("C", 0.9));
}
}
And MinTcpRow ( is faulted because it won't notify change ) but looks the same.
public class MinTcpRow
{
public string StructureId { get; }
public double MinTcpValue { get; set; }
public MinTcpRow(string structureId, double minTcpValue)
{
if (minTcpValue < 0 || minTcpValue > 1)
throw new ArgumentOutOfRangeException($"{nameof(minTcpValue)} must " +
$"be in range [0, 1], but was {minTcpValue}.");
StructureId = structureId ?? throw new ArgumentNullException(nameof(structureId));
MinTcpValue = minTcpValue;
And that works, no error anyhow. There is a memory leak waiting to catch you out because of not implementing inpc but I get no error like you show us. Are you somehow using a different version of MinTcpRow?
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.