0

类似于WPF - 帮助将 XAML 绑定表达式转换为代码隐藏

我正在尝试使用绑定来更改 DataGridTextColumn 中某些元素的颜色。因为我需要在单独的选项卡中任意数量的 DataGrid,所以我在代码隐藏中迭代地创建它们。这是我创建列的代码:

// create a value column
column = new DataGridTextColumn();
column.Binding = new Binding("Value");
BindingOperations.SetBinding(column, DataGridTextColumn.ForegroundProperty, new Binding("TextColor"));
listGrid.Columns.Add(column);

Value 绑定工作正常,但 TextColor 属性的 getter 永远不会被调用。

网格的 ItemsSource 属性设置为 VariableWatcher 对象的列表,以下是它的一些属性:

public bool Value
{
    get { return _variable.Value; }
}
// used to set DataGridTextColumn.Foreground
public Brush TextColor
{
    get
    {
        Color brushColor;
         if (_valueChanged)
            brushColor = Color.FromRgb(255, 0, 0);
        else
            brushColor = Color.FromRgb(0, 0, 0);
         return new SolidColorBrush(brushColor);
    }
}

VariableWatcher 实现 INotifyPropertyChanged 如下:

public event PropertyChangedEventHandler PropertyChanged;
public void NotifyPropertyChanged(string info)
{
    if (PropertyChanged != null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(info));
    }
}

在 VariableWatcher 的一种方法中,我有以下几行:

_valueChanged = true;
NotifyPropertyChanged("Value");
NotifyPropertyChanged("TextColor");

跨过“Value”行会激活 Value getter 中的断点,并在显示中更新 Value 文本。但是,跨过“TextColor”行不会激活 TextColor getter 中的断点,并且文本颜色不会改变。知道这里发生了什么吗?

编辑:这是答案,感谢大马士革。(我会将此放在对他的回答的评论中,但它不会正确格式化我的代码。)我将此添加到 XAML 文件中:

<Window.Resources>
    <Style x:Key="BoundColorStyle" TargetType="{x:Type TextBlock}">
        <Setter Property="Foreground" Value="{Binding TextColor}" />
    </Style>
</Window.Resources>

在 C# 代码中,我将 BindingOperations 行替换为

column.ElementStyle = this.FindResource("BoundColorStyle") as Style;
4

3 回答 3

1

解决方法:

在您的资源中创建一个样式,如下所示:

<Style x:Key="MyStyle" TargetType="{x:Type TextBlock}">
  <Setter Property="Foreground" Value="{Binding TextColor}" />
</Style>

ElementStyle并在您的属性中设置此样式DataGridColumn,应该类似于您的代码中的内容:

column = new DataGridTextColumn();
column.Style = this.FindResource("MyStyle") as Style;

其原因是ElementStyle直接在列的内容中起作用(即TextBlock显示值)

于 2012-10-25T18:30:50.780 回答
1

它也可以通过没有样式的代码来实现。 重要的一点是为为目标属性设置的新绑定表达式显式设置绑定源(查看下面的代码)

在本例中,DataGrid 生成动态列,并以CollectionViewSource 对象(即cycleDataview)为界,cycleDataview 的源是ObservableCollection 的对象,即cycleRecord。

// Create view source

this.cycleDataview = new CollectionViewSource();
this.cycleDataview.Source = this.cycleRecords;

 // Set Item Source to data grid
 this.DataGridCycleData.ItemsSource = this.cycleDataview.View;

// Generate Columns for datagrid
 var columns = this.cycleRecords.First().CyclePartCols.Select((x, i) => new {PreDescriptor =  x.PreDescriptor, Index = i }).ToArray();

foreach (var column in columns)
{

  Binding binding = new Binding(string.Format("CyclePartCols[{0}].PartValue", column.Index));

  Binding bindingColor = new Binding(string.Format("CyclePartCols[{0}].TextColor", column.Index));
  **bindingColor.Source = this.cycleRecords;** // Binding source is required to set

  DataGridTextColumn dgc = new DataGridTextColumn();


  txtblckCol.Text = column.PreDescriptor;
  dgc.Header = txtblckCol;
  dgc.Binding = binding;
  this.DataGridCycleData.Columns.Add(dgc);
  BindingOperations.SetBinding(dgc, DataGridTextColumn.ForegroundProperty, bindingColor);                

}

于 2014-06-30T19:16:22.747 回答
0

使用大马士革的解决方法,但只能使用后面的代码:

var myStyle = new Style
{
   TargetType = typeof(TextBlock)
};
textColumnStyleExt.Setters.Add(new Setter(TextBlock.ForegroundProperty, new Binding("TextColor"));
column = new DataGridTextColumn();
column.Binding = new Binding("Value");
column.ElementStyle = myStyle;
于 2020-10-13T13:27:11.303 回答