在数据网格行中每列分隔 object
Seperate object per column in a datagrid row
我有一个来自 SCADA 软件的数据网格,我正在通过创建可用于更多用例的自定义用户控件在 WPF 中重新创建它。我有一个 SettingRow 类型的可观察 collection,它包含 one 单元格的数据。问题是它不包含一个单元格的数据。
如果我的 collection 中有 10 个项目,那么我在第 1 行第 3 列中看不到单独的项目。我在例如第 1 行第 2 列中看到相同的项目。简而言之:无论我 select 连续在哪一列,我都看到相同的 SettingRow object。
每个单元格都是一个单独的设置 object,绑定到 DataTemplateSelector 到 select 适当的数据模板以显示值(布尔值作为复选框,字符串和值作为文本框等)
我创建了一个具有模板select或基于 SettingRow class 中的值的 DataGrid。数据网格的项目源当前绑定到我的视图模型中的 ObservableCollection。它有效,我在每行的每个单元格中看到每个 SettingRow,但我很确定我在每一列中看到相同的 SettingRow,它不是独立于 object 的单独 object在那一列之前。
我在 Whosebug 上尝试了一些解决方案,在可观察对象 collection 中使用可观察对象 collection,但我并没有真正让它工作。
下面是每行显示的 class。 object 是否被复制到下一列?还是每一列都一样 object re-used?
public class SettingRow : ObservableObject
{
public int ID { get; set; }
public object Value { get; set; }
public string Name { get; set; }
public string Unit { get; set; }
}
我在 XAML 中的数据网格已声明,但只有名称 属性。其余通过代码添加。
<DataGrid x:Name="OverviewDataGridView" ItemsSource="{Binding SettingsCollection, Mode=TwoWay}" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}">
</DataGridTextColumn>
</DataGrid.Columns>
下面我为每个阶段创建一个列。这 4 个阶段是模拟的,因为我没有实际数据。现在,每个 SettingRow 都应该是单独可编辑的,我需要从 ViewModel 中检索它。
这在后面的代码中。
public void GenerateColumns()
{
//Simulate 4 phases and adding a column per phase!
for(int i = 0; i < 4; i++)
{
DataGridTemplateColumn templateCol = new DataGridTemplateColumn();
templateCol.Header = "Phase " + i;
TemplateSelector templateSel = new TemplateSelector();
templateSel.BooleanTemplate = this.Resources["BooleanTemplate"] as DataTemplate;
templateSel.TextTemplate = this.Resources["TextTemplate"] as DataTemplate;
templateCol.CellTemplateSelector = templateSel;
this.OverviewDataGridView.Columns.Add(templateCol);
}
}
ViewModel 非常简单,它创建了一些测试数据。创建的每个 SettingRow 都显示在每一列中,但我想我在每个
中看到相同的 object
public class DynamicDataGridViewModel : ObservableObject
{
private ObservableCollection<SettingRow> settingsCollection;
public ObservableCollection<SettingRow> SettingsCollection
{
get { return settingsCollection; }
set
{
settingsCollection = value;
RaisePropertyChangedEvent("SettingsCollection");
}
}
public DynamicDataGridViewModel()
{
SettingsCollection = new ObservableCollection<SettingRow>();
SettingsCollection.Add(new SettingRow() { ID = 0, Name = "Phase Active", Value = true, Unit = "" });
SettingsCollection.Add(new SettingRow() { ID = 1, Name = "Minimum phase duration", Value = +900, Unit = "s" });
SettingsCollection.Add(new SettingRow() { ID = 2, Name = "Min Supply air temperature", Value = 50.0302, Unit = "C" });
}
}
最后,我的 DataTemplateSelector。它只处理 SettingRow 的值并显示正确的符号(boolean = checkbox 等)
public class TemplateSelector : DataTemplateSelector
{
public DataTemplate BooleanTemplate { get; set; }
public DataTemplate TextTemplate { get; set; }
public SettingRow Content { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ContentPresenter presenter = container as ContentPresenter;
DataGridCell cell = presenter.Parent as DataGridCell;
SettingRow row = (cell.DataContext as SettingRow);
if(row != null && row.Value != null)
{
this.Content = row;
switch (Type.GetTypeCode(row.Value.GetType()))
{
case TypeCode.Boolean:
return BooleanTemplate;
default:
return TextTemplate;
}
}
else
{
return null;
}
}
}
编辑:
以下各栏的模板
<DataTemplate x:Key="BooleanTemplate">
<StackPanel Orientation="Horizontal" Margin="2">
<CheckBox IsChecked="{Binding Value}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="TextTemplate">
<StackPanel Orientation="Horizontal" Margin="2">
<TextBox Height="25" MinWidth="70" FontSize="14">
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Value" Mode="TwoWay"/>
<Binding Path="Unit" Mode="TwoWay"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
</StackPanel>
</DataTemplate>
我需要的是绑定到可观察对象的 DataGrid collection。它具有动态数量的列(代表一个阶段),我需要在每一列中有一个 SettingRow 并且它可以根据 object 进行编辑。例如,我可以将调平阶段中的阶段持续时间设置的可见性设置为不可见。
编辑 2:
我的想法是在一个可观察对象 collection 中使用一个可观察对象 collection 就像下面的代码片段这样我可以将我的数据表示为每一行中的列。这样我就可以访问每一行和每一列个人 object.:
private ObservableCollection<ObservableCollection<SettingRow>> items;
public ObservableCollection<ObservableCollection<SettingRow>> ItemsSourceOfDataGrid
{
get { return items; }
set
{
items = value;
RaisePropertyChangedEvent("ItemsSourceOfDataGrid")
}
}
编辑:因此,在查看了评论和您想要的内容之后,最简单的事情就是定义所有行名称,然后让 ObservableCollection
成为列而不是行的集合。如果您想走动态行和列的疯狂路线,那么这些可以帮助您入门:
https://svitla.com/blog/grid-with-dynamic-number-of-rows-and-columns-part-1
https://svitla.com/blog/grid-with-dynamic-number-of-rows-and-columns-part-2
来源Github:https://github.com/IReznykov/Blog
因此,使用动态列的方法非常简单。
重申一下:
确保您的 RaisePropertyChangedEvent
已添加到模型中的项目中。这将允许它们在您的 SettingsCollection
中动态更改。此外,您的 DataGrid
的 XAML 部分需要以某种方式设置才能使用此功能。
public class SettingColumn : ObservableObject
{
public int _PhaseNumber;
public int PhaseNumber
{
get { return _PhaseNumber; }
set
{
PhaseNumber = value;
RaisePropertyChangedEvent("PhaseNumber");
}
}
public object _MinPhaseDuration;
public object MinPhaseDuration
{
get { return _Value; }
set
{
Value = value;
RaisePropertyChangedEvent("Value");
}
}
public string _MinSupplyAirTemp;
public string MinSupplyAirTemp
{
get { return _MinSupplyAirTemp; }
set
{
MinSupplyAirTemp = value;
RaisePropertyChangedEvent("MinSupplyAirTemp");
}
}
// The rest of your row labels here.
.
.
.
希望此编辑对您有所帮助。同样,动态行和列很痛苦。为自己省去一些麻烦并定义所有行标签或列标签。
我有一个来自 SCADA 软件的数据网格,我正在通过创建可用于更多用例的自定义用户控件在 WPF 中重新创建它。我有一个 SettingRow 类型的可观察 collection,它包含 one 单元格的数据。问题是它不包含一个单元格的数据。
如果我的 collection 中有 10 个项目,那么我在第 1 行第 3 列中看不到单独的项目。我在例如第 1 行第 2 列中看到相同的项目。简而言之:无论我 select 连续在哪一列,我都看到相同的 SettingRow object。
每个单元格都是一个单独的设置 object,绑定到 DataTemplateSelector 到 select 适当的数据模板以显示值(布尔值作为复选框,字符串和值作为文本框等)
我创建了一个具有模板select或基于 SettingRow class 中的值的 DataGrid。数据网格的项目源当前绑定到我的视图模型中的 ObservableCollection。它有效,我在每行的每个单元格中看到每个 SettingRow,但我很确定我在每一列中看到相同的 SettingRow,它不是独立于 object 的单独 object在那一列之前。
我在 Whosebug 上尝试了一些解决方案,在可观察对象 collection 中使用可观察对象 collection,但我并没有真正让它工作。
下面是每行显示的 class。 object 是否被复制到下一列?还是每一列都一样 object re-used?
public class SettingRow : ObservableObject
{
public int ID { get; set; }
public object Value { get; set; }
public string Name { get; set; }
public string Unit { get; set; }
}
我在 XAML 中的数据网格已声明,但只有名称 属性。其余通过代码添加。
<DataGrid x:Name="OverviewDataGridView" ItemsSource="{Binding SettingsCollection, Mode=TwoWay}" AutoGenerateColumns="True">
<DataGrid.Columns>
<DataGridTextColumn Header="Name" Binding="{Binding Name}">
</DataGridTextColumn>
</DataGrid.Columns>
下面我为每个阶段创建一个列。这 4 个阶段是模拟的,因为我没有实际数据。现在,每个 SettingRow 都应该是单独可编辑的,我需要从 ViewModel 中检索它。
这在后面的代码中。
public void GenerateColumns()
{
//Simulate 4 phases and adding a column per phase!
for(int i = 0; i < 4; i++)
{
DataGridTemplateColumn templateCol = new DataGridTemplateColumn();
templateCol.Header = "Phase " + i;
TemplateSelector templateSel = new TemplateSelector();
templateSel.BooleanTemplate = this.Resources["BooleanTemplate"] as DataTemplate;
templateSel.TextTemplate = this.Resources["TextTemplate"] as DataTemplate;
templateCol.CellTemplateSelector = templateSel;
this.OverviewDataGridView.Columns.Add(templateCol);
}
}
ViewModel 非常简单,它创建了一些测试数据。创建的每个 SettingRow 都显示在每一列中,但我想我在每个
中看到相同的 objectpublic class DynamicDataGridViewModel : ObservableObject
{
private ObservableCollection<SettingRow> settingsCollection;
public ObservableCollection<SettingRow> SettingsCollection
{
get { return settingsCollection; }
set
{
settingsCollection = value;
RaisePropertyChangedEvent("SettingsCollection");
}
}
public DynamicDataGridViewModel()
{
SettingsCollection = new ObservableCollection<SettingRow>();
SettingsCollection.Add(new SettingRow() { ID = 0, Name = "Phase Active", Value = true, Unit = "" });
SettingsCollection.Add(new SettingRow() { ID = 1, Name = "Minimum phase duration", Value = +900, Unit = "s" });
SettingsCollection.Add(new SettingRow() { ID = 2, Name = "Min Supply air temperature", Value = 50.0302, Unit = "C" });
}
}
最后,我的 DataTemplateSelector。它只处理 SettingRow 的值并显示正确的符号(boolean = checkbox 等)
public class TemplateSelector : DataTemplateSelector
{
public DataTemplate BooleanTemplate { get; set; }
public DataTemplate TextTemplate { get; set; }
public SettingRow Content { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
ContentPresenter presenter = container as ContentPresenter;
DataGridCell cell = presenter.Parent as DataGridCell;
SettingRow row = (cell.DataContext as SettingRow);
if(row != null && row.Value != null)
{
this.Content = row;
switch (Type.GetTypeCode(row.Value.GetType()))
{
case TypeCode.Boolean:
return BooleanTemplate;
default:
return TextTemplate;
}
}
else
{
return null;
}
}
}
编辑:
以下各栏的模板
<DataTemplate x:Key="BooleanTemplate">
<StackPanel Orientation="Horizontal" Margin="2">
<CheckBox IsChecked="{Binding Value}"/>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="TextTemplate">
<StackPanel Orientation="Horizontal" Margin="2">
<TextBox Height="25" MinWidth="70" FontSize="14">
<TextBox.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="Value" Mode="TwoWay"/>
<Binding Path="Unit" Mode="TwoWay"/>
</MultiBinding>
</TextBox.Text>
</TextBox>
</StackPanel>
</DataTemplate>
我需要的是绑定到可观察对象的 DataGrid collection。它具有动态数量的列(代表一个阶段),我需要在每一列中有一个 SettingRow 并且它可以根据 object 进行编辑。例如,我可以将调平阶段中的阶段持续时间设置的可见性设置为不可见。
编辑 2:
我的想法是在一个可观察对象 collection 中使用一个可观察对象 collection 就像下面的代码片段这样我可以将我的数据表示为每一行中的列。这样我就可以访问每一行和每一列个人 object.:
private ObservableCollection<ObservableCollection<SettingRow>> items;
public ObservableCollection<ObservableCollection<SettingRow>> ItemsSourceOfDataGrid
{
get { return items; }
set
{
items = value;
RaisePropertyChangedEvent("ItemsSourceOfDataGrid")
}
}
编辑:因此,在查看了评论和您想要的内容之后,最简单的事情就是定义所有行名称,然后让 ObservableCollection
成为列而不是行的集合。如果您想走动态行和列的疯狂路线,那么这些可以帮助您入门:
https://svitla.com/blog/grid-with-dynamic-number-of-rows-and-columns-part-1 https://svitla.com/blog/grid-with-dynamic-number-of-rows-and-columns-part-2
来源Github:https://github.com/IReznykov/Blog
因此,使用动态列的方法非常简单。
重申一下:
确保您的 RaisePropertyChangedEvent
已添加到模型中的项目中。这将允许它们在您的 SettingsCollection
中动态更改。此外,您的 DataGrid
的 XAML 部分需要以某种方式设置才能使用此功能。
public class SettingColumn : ObservableObject
{
public int _PhaseNumber;
public int PhaseNumber
{
get { return _PhaseNumber; }
set
{
PhaseNumber = value;
RaisePropertyChangedEvent("PhaseNumber");
}
}
public object _MinPhaseDuration;
public object MinPhaseDuration
{
get { return _Value; }
set
{
Value = value;
RaisePropertyChangedEvent("Value");
}
}
public string _MinSupplyAirTemp;
public string MinSupplyAirTemp
{
get { return _MinSupplyAirTemp; }
set
{
MinSupplyAirTemp = value;
RaisePropertyChangedEvent("MinSupplyAirTemp");
}
}
// The rest of your row labels here.
.
.
.
希望此编辑对您有所帮助。同样,动态行和列很痛苦。为自己省去一些麻烦并定义所有行标签或列标签。