我遇到了一个问题,试图通过搜索来解决,但没有成功。因此,我在这里尝试具体的帮助:我有一个带有不同标签的MainWindow应用程序。一个标签应该有一个带有4列的DataGrid。我想用一个对象列表来填充它们。我在MainWindow.xaml.cs中的实现:
// 4 times this kind of Code
private ObservableCollection<bool> _StatusBitsSimulateActiveList = null;
private ObservableCollection<string> _StatusBitsNameList = null;
private ObservableCollection<bool> _ActualStatusBitsList = null;
private ObservableCollection<bool> _SimulatedStatusBitsList = null;
public ObservableCollection<bool> StatusBitsSimulateActiveList
{
get
{
List<bool> list = Manager._StatusBits.GetSimulatedStatusBitsList();
_StatusBitsSimulateActiveList = new ObservableCollection<bool>(list);
return _StatusBitsSimulateActiveList;
}
set
{
_StatusBitsSimulateActiveList = value;
OnPropertyChanged();
}
}
MainWindow.xaml文件包含:
<DataGrid x:Name="SimulatedBitsDataGrid" MinRowHeight="25" AutoGenerateColumns="False"
Margin="5" AlternatingRowBackground="LightBlue" AlternationCount="2" Grid.Row="3" Grid.Column="0" ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridCheckBoxColumn Binding="{Binding StatusBitsSimulateActiveList, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Simulation Active"/>
<DataGridTemplateColumn Width="*" Header="Status Bits Name">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<Binding Mode="TwoWay" Path="StatusBitsNameList"></Binding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Binding="{Binding ActualStatusBitsList, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Status Bit SPS"/>
<DataGridCheckBoxColumn Binding="{Binding SimulatedStatusBitsList, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Simulated Value"/>
</DataGrid.Columns>
</DataGrid>
我有一个类,其中的数据是存储和检索(见管理器._StatusBits)与一些方法来获取和设置数据。数据网格是不是填充数据。有人可以帮助?
我尝试通过ItemsSource=“Binding”然后绑定到列表。没有工作。在互联网上看了看,没有找到解决方案,可能我不明白的机制。我是相当新的wpf,只在C++和mfc工作。
***编辑:***所以我尝试了一些答案,现在了解了一些。但有一个问题我无法解决。我没有尝试过使用这些类型的ViewModel(也许这会有帮助,现在不尝试)。下面是我的代码,它是单向工作的,但不是双向工作的,因为没有注意到GUI与网格的交互。缺少什么?注意,这段代码有一部分是别人写的,我试图解决一些问题并添加一些特性:
MainWindow.xaml.cs
InitializeComponent();
this.DataContext = this; // Why do someone need to do this? Because of relativeSource Binding? see .xaml file
StatusBitDataGrid.DataContext = Manager._StatusBits.dataList; // there is a manager, which manages the objects, the Manager is created in the MainWindow
MainWindow.xaml
<Window x:Class="APP.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Title="EFEM-Client Plus+" Height="900" Width="1200"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
WindowStartupLocation="CenterScreen"
Closing="OnWindowClosing"
x:Name="window1"
>
<DataGrid x:Name="StatusBitDataGrid" Grid.Row="2" Grid.RowSpan="3" Grid.Column="0" Grid.ColumnSpan="4"
ItemsSource="{Binding}" CanUserAddRows="False" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridCheckBoxColumn CanUserSort="False" Binding="{Binding SimulateActive, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Simulation Active"/>
<DataGridTemplateColumn Width="*" Header="Status Bits Name" CanUserSort="False">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock>
<TextBlock.Text>
<Binding Mode="TwoWay" Path="StatusBitsName"></Binding>
</TextBlock.Text>
</TextBlock>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridCheckBoxColumn Binding="{Binding ActualBitValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Status Bit SPS" CanUserSort="False" IsReadOnly="True"/>
<DataGridCheckBoxColumn Binding="{Binding SimulatedBitValue, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" Header="Simulated Value" CanUserSort="False"/>
</DataGrid.Columns>
</DataGrid>
StatusBits.cs
public class StatusBits {
[...]
public StatusBits()
{
[...]
PopulateObservable();
}
[...]
private ObservableCollection<StatusBitsSingleData> _dataList = new ObservableCollection<StatusBitsSingleData>();
public ObservableCollection<StatusBitsSingleData> dataList
{
get { return _dataList; }
set { _dataList = value; } // Code and Style never enters the setter...
}
private void PopulateObservable()
{
dataList.Clear();
for (int i = 0; i < maxSemDexStatus; i++)
{
dataList.Add(new StatusBitsSingleData(StatusBitsSimulateActive[i], StatusBitsName[i], ActualStatusBits[i], SimulatedStatusBits[i]));
}
}
[...]
// The SingleData Class, here the setter is used by the program
public class StatusBitsSingleData
{
public bool SimulateActive { get; set; }
public string StatusBitsName { get; set; }
public bool ActualBitValue { get; set; }
public bool SimulatedBitValue { get; set; }
public StatusBitsSingleData(bool simA, string name, bool actu, bool sim)
{
SimulateActive = simA; StatusBitsName = name; ActualBitValue = actu; SimulatedBitValue = sim;
}
}
}
因为setter是在公共类StatusBitsSingleData中使用的,所以我尝试制作一个自定义通告程序,但是失败了...
2条答案
按热度按时间fnvucqvd1#
所以我认为我对wpf的问题有一个基本的误解。所以我尝试了一个反映首要问题的基本项目:主窗口.xaml包含
Data.cs包含:
这不起作用。列表已填充,但绑定不起作用。这里缺少什么?
7uhlpewt2#
有几个问题需要说明。
DataGrid
只能绑定到一个ObservableCollection
。DataGrid.Column
绑定到ObservableCollection
中包含的类类型的单个属性ObservableCollection
实作INotifyProperty
界面,因此在系结时不需要进一步的程式码支援。我不知道你想用你的代码做什么,但首先我会把你想在
DataGrid.Row
中显示的所有数据合并到一个类类型中,并拥有一个包含该类型的ObservableCollection
的视图模型。我不建议使用
ObservableCollection
的getter来填充它的数据源,而是使用ViewMode函数来填充它,这里我使用了RelayCommand
(ICommand
实现),但是您可以链接到一些自动化的数据源,例如Web API或数据库。因此,这里有一个合适的ViewModel -注意,
IStatusBitsDataViewModel
是一个接口类型,它只定义了StatusBitsDataViewModel
的公共部分。现在,您的视图将需要对ViewModel进行
DataContext
设置,我倾向于在视图代码隐藏文件(例如与之关联的.cs
文件)中进行此设置,因为我可以使用依赖注入并向其传递具体类型,从而在运行时更改行为(例如:在使用真实的数据源的ViewModel和使用预定义测试数据的ViewModel之间切换,比如说用于单元测试。因此,背后的代码是:
下面是一个示例窗口的XAML,它演示了数据绑定以及如何使用UI中的数据触发
DataGrid
的填充。我希望这对你有帮助。
Edit由于您现在询问如何更改
DataGrid
中的数据并将其传递回去,因此您需要进行一些细微的更改,以便更改数据的操作实际上触发绑定类中的数据更改。让我们更改数据列类,使该部分现在为:
使用布尔值时,显示和更改复选框值比更改文本更容易。
指定何时触发绑定属性的更新事件是这里的关键。(提示在
StatusBitClass
属性setter上放置一个断点以证明它是有效的)。如果您希望以编程方式更改
StatusBitClass
属性值,并在DataGrid
中更新它们,则需要确保这些属性支持INotifyPropertyChanged
。您可以创建一个单独的ViewModel类,或者只让
StatusBitClass
实现INotifyPripertyChanged
。现在,如果您在将
StatusBitClass
属性值添加到ObservableCollection
之后更改它,您将看到DataGrid
中的值更新,如果没有它,您将需要通过其他方法强制刷新窗口。