- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在 WPF MVVM 中创建动态 UI 应用程序,它将 UI 区域绑定(bind)到我的自定义 UIField
类的集合。
UIField
包含许多 BindingProperty
属性,允许我指定 Control
将绑定(bind)到的属性。
public abstract class UIField : BaseObject
{
BindingProperty property, isReadonly = new BindingProperty(false, false);
object dataContext;
public BindingProperty Property
{
get { return property; }
set { SetProperty(ref property, value, () => Property); }
}
public BindingProperty IsReadonly
{
get { return isReadonly; }
set { SetProperty(ref isReadonly, value, () => IsReadonly); }
}
public object DataContext
{
get { return dataContext; }
set { SetProperty(ref dataContext, value, () => DataContext); }
}
}
在 ResourceDictionary
中,我模板化了 UIField
的派生类
<DataTemplate DataType="{x:Type fields:TextBoxField}">
<TextBox metro:TextBoxHelper.Watermark="{e:IndirectBinding Watermark}"
metro:TextBoxHelper.UseFloatingWatermark="{e:IndirectBinding UseFloatingWatermark}"
IsReadOnly="{e:IndirectBinding IsReadonly}"
Text="{e:IndirectBinding Property}"
/>
</DataTemplate>
然后我在 View 模型中创建这些字段并将它们添加到集合中。然后,UI 使用 ItemsControl
new TextBoxField()
{
DataContext = this,
Property = new BindingProperty(() => ((SalesOrder)Order).SecondSalesReference),
Watermark = new BindingProperty("Customer Ref. Number", false),
UseFloatingWatermark = new BindingProperty(true, false)
}
这对于普通字段非常有用,但我遇到了 DataGrid
的问题。
最好,我希望能够绑定(bind)已扩展的 UIField
集合,为 DataGrid
的列提供 Header 属性,然后绑定(bind)模板这些到 DataGridColumn
,但您不能在 DataTemplate
中有 DataGridColumn
。
目前,我已经创建了一个界面,为我提供标题、DataGridColumn
类型和每个单元格中应包含的内容:
public interface IDataGridField
{
string Header { get; set; }
Type ColumnType { get; }
UIField CellContents { get; }
}
然后我使用以下方法将它们绑定(bind)到 DataGrid
的列:
public class DataGridHelper
{
public static readonly DependencyProperty BindableColumnsProperty = DependencyProperty.RegisterAttached("BindableColumns", typeof(ThreadSafeCollection<IDataGridField>), typeof(DataGridHelper),new UIPropertyMetadata(null, BindableColumnsPropertyChanged));
static void BindableColumnsPropertyChanged(DependencyObject source, DependencyPropertyChangedEventArgs e)
{
var dataGrid = source as DataGrid;
var columns = e.NewValue as ThreadSafeCollection<IDataGridField>;
dataGrid.Columns.Clear();
if (columns == null)
return;
foreach (var column in columns)
{
var newColumn = Utility.CreateInstance(column.ColumnType) as DataGridColumn;
newColumn.Header = column.Header;
dataGrid.Columns.Add(newColumn);
}
}
public static void SetBindableColumns(DependencyObject element, ThreadSafeCollection<IDataGridField> value)
{
element.SetValue(BindableColumnsProperty, value);
}
public static ThreadSafeCollection<IDataGridField> GetBindableColumns(DependencyObject element)
{
return (ThreadSafeCollection<IDataGridField>)element.GetValue(BindableColumnsProperty);
}
}
这将为我提供带有标题但在 DataGridCell
中没有内容的列。
如何设置创建的 DataGridColumn
中每个单元格的内容?
编辑 1(进度?):
我意识到生成的 DataGridColumn
必须是 DataGridTemplateColumn
,因此这会打开更多属性。
我修改了 IDataGridField
,将 UIField
属性更改为 Type
。
然后,在生成新的 DataGridColumn
时,我只获取分配给所选 Type
的 DataTemplate
foreach (var column in columns)
{
var newColumn = new DataGridTemplateColumn();
var key = new DataTemplateKey(column.CellContentType);
var template = Application.Current.FindResource(key) as DataTemplate;
newColumn.CellTemplate = template;
newColumn.Header = column.Header;
dataGrid.Columns.Add(newColumn);
}
我认为现在唯一的问题是应用绑定(bind)。
最佳答案
看来你想重新发明轮子。 WPF DataGrid 已经很好地处理基本的数据类型,如字符串、 bool 、整数。但是您会有自己的理由。
我认为如果您想采用动态方法,您需要设置 CellTemplate
或/和 CellEditingTemplate
而不是创建“正确”的列类型。这也适用于更复杂的数据类型。
这只是 XAML,但它应该显示您可以前进的方向:
<DataGrid ItemsSource="{Binding}">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBox metro:TextBoxHelper.Watermark="{e:IndirectBinding Watermark}"
metro:TextBoxHelper.UseFloatingWatermark="{e:IndirectBinding UseFloatingWatermark}"
IsReadOnly="{e:IndirectBinding IsReadonly}"
Text="{e:IndirectBinding Property}"
/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
您还可以使用数据网格的 AutoGeneratingColumn
事件来覆盖列的创建。也许您想派生您的 CustomDataGrid?
private void DataGrid_AutoGeneratingColumn(object sender, System.Windows.Controls.DataGridAutoGeneratingColumnEventArgs e)
{
//check for the type
if (e.PropertyType == typeof(TextField))
{
DataGridTemplateColumn newDataGridTemplateColumn = new DataGridTemplateColumn();
e.Column = newDataGridTemplateColumn;
//do some datatemplate voodoo, maybe you want to load it from resources or similar
StringReader stringReader = new StringReader(
@"<DataTemplate
xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"">
<" + typeof(ComboBox).Name + @" Text=""{Binding " + "Text" + @"}""/>
</DataTemplate>");
XmlReader xmlReader = XmlReader.Create(stringReader);
DataTemplate template = XamlReader.Load(xmlReader) as DataTemplate;
newDataGridTemplateColumn.CellTemplate = template;
}
}
关于c# - 动态设置 DataGridColumn 的单元格内容,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40608915/
#include using namespace std; class C{ private: int value; public: C(){ value = 0;
这个问题已经有答案了: What is the difference between char a[] = ?string?; and char *p = ?string?;? (8 个回答) 已关闭
关闭。此题需要details or clarity 。目前不接受答案。 想要改进这个问题吗?通过 editing this post 添加详细信息并澄清问题. 已关闭 7 年前。 此帖子已于 8 个月
除了调试之外,是否有任何针对 c、c++ 或 c# 的测试工具,其工作原理类似于将独立函数复制粘贴到某个文本框,然后在其他文本框中输入参数? 最佳答案 也许您会考虑单元测试。我推荐你谷歌测试和谷歌模拟
我想在第二台显示器中移动一个窗口 (HWND)。问题是我尝试了很多方法,例如将分辨率加倍或输入负值,但它永远无法将窗口放在我的第二台显示器上。 关于如何在 C/C++/c# 中执行此操作的任何线索 最
我正在寻找 C/C++/C## 中不同类型 DES 的现有实现。我的运行平台是Windows XP/Vista/7。 我正在尝试编写一个 C# 程序,它将使用 DES 算法进行加密和解密。我需要一些实
很难说出这里要问什么。这个问题模棱两可、含糊不清、不完整、过于宽泛或夸夸其谈,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开,visit the help center . 关闭 1
有没有办法强制将另一个 窗口置于顶部? 不是应用程序的窗口,而是另一个已经在系统上运行的窗口。 (Windows, C/C++/C#) 最佳答案 SetWindowPos(that_window_ha
假设您可以在 C/C++ 或 Csharp 之间做出选择,并且您打算在 Windows 和 Linux 服务器上运行同一服务器的多个实例,那么构建套接字服务器应用程序的最明智选择是什么? 最佳答案 如
你们能告诉我它们之间的区别吗? 顺便问一下,有什么叫C++库或C库的吗? 最佳答案 C++ 标准库 和 C 标准库 是 C++ 和 C 标准定义的库,提供给 C++ 和 C 程序使用。那是那些词的共同
下面的测试代码,我将输出信息放在注释中。我使用的是 gcc 4.8.5 和 Centos 7.2。 #include #include class C { public:
很难说出这里问的是什么。这个问题是含糊的、模糊的、不完整的、过于宽泛的或修辞性的,无法以目前的形式得到合理的回答。如需帮助澄清此问题以便重新打开它,visit the help center 。 已关
我的客户将使用名为 annoucement 的结构/类与客户通信。我想我会用 C++ 编写服务器。会有很多不同的类继承annoucement。我的问题是通过网络将这些类发送给客户端 我想也许我应该使用
我在 C# 中有以下函数: public Matrix ConcatDescriptors(IList> descriptors) { int cols = descriptors[0].Co
我有一个项目要编写一个函数来对某些数据执行某些操作。我可以用 C/C++ 编写代码,但我不想与雇主共享该函数的代码。相反,我只想让他有权在他自己的代码中调用该函数。是否可以?我想到了这两种方法 - 在
我使用的是编写糟糕的第 3 方 (C/C++) Api。我从托管代码(C++/CLI)中使用它。有时会出现“访问冲突错误”。这使整个应用程序崩溃。我知道我无法处理这些错误[如果指针访问非法内存位置等,
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,因为
我有一些 C 代码,将使用 P/Invoke 从 C# 调用。我正在尝试为这个 C 函数定义一个 C# 等效项。 SomeData* DoSomething(); struct SomeData {
这个问题已经有答案了: Why are these constructs using pre and post-increment undefined behavior? (14 个回答) 已关闭 6
我是一名优秀的程序员,十分优秀!