缺乏关于该主题的问题可能表明这里有代码异味,但是......是否可以像编写属性一样为类编写扩展方法并将数据绑定(bind)到该方法?
假设为我提供了一个我无法从根本上改变的类结构,但我想将其一系列 bool 属性表示为用于显示目的的字符串。
简化的基类:
public class Transmission
{
public int ID { get; set; }
public bool Cancelled { get; set; }
public bool Stored { get; set; }
public bool Recorded { get; set; }
}
我的扩展方法:
public static class Extensions
{
public static string Status(this Transmission trans)
{
StringBuilder sb = new StringBuilder("|");
if (trans.Cancelled)
sb.Append("| Cancelled ");
if (trans.Recorded)
sb.Append("| Recorded ");
if (trans.Stored)
sb.Append("| Stored ");
sb.Append("||");
return sb.ToString();
}
}
为了进一步增加复杂性,我正在传递这些内容的列表,并且我正在尝试绑定(bind)到数据网格(XAML 经验严重受限)。
<GroupBox Header="Here is an amazing list of results for you to violate horribly.">
<DataGrid ItemsSource="{Binding Transmissions, Mode=OneWay}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Width="*" Header="Local ID" Binding="{Binding ID, Mode=OneWay}"/>
<DataGridTextColumn Width="*" Header="Status" Binding="{Binding Status, Mode=OneWay}"/>
</DataGrid.Columns>
</DataGrid>
</GroupBox>
我已经测试了代码并且能够毫无困难地绑定(bind)到 ID。然而,“状态”根本没有被接受。是否有绑定(bind)到扩展属性的技巧?或者只写一个装饰器/外观类并绑定(bind)到它会更谨慎吗?
最佳答案
当您传递传输对象列表时,您可以使用外观模式并将它们存储在设计的容器中...
public class TransmissionContainer : INotifyPropertyChanged
{
private readonly Transmission _transmission;
public TransmissionContainer(Transmission transmission)
{
_transmission = transmission;
}
private int _id;
public int Id
{
[DebuggerStepThrough]
get { return _transmission.ID; }
[DebuggerStepThrough]
set
{
if (value != _transmission.ID)
{
_transmission.ID = value;
OnPropertyChanged("Id");
}
}
}
public bool Cancelled
{
[DebuggerStepThrough]
get { return _transmission.Cancelled }
[DebuggerStepThrough]
set
{
if (value != _transmission.Cancelled)
{
_transmission.Cancelled = value;
OnPropertyChanged("Cancelled");
OnPropertyChanged("Status");
}
}
}
public string Status
{
[DebuggerStepThrough]
get
{
StringBuilder sb = new StringBuilder("|");
if (_transmission.Cancelled)
sb.Append("| Cancelled ");
if (_transmission.Recorded)
sb.Append("| Recorded ");
if (_transmission.Stored)
sb.Append("| Stored ");
sb.Append("||");
return sb.ToString();
}
}
//
// code in other properties here
//
#region INotifyPropertyChanged Implementation
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string name)
{
var handler = System.Threading.Interlocked.CompareExchange(ref PropertyChanged, null, null);
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
#endregion
}
这是一个容器类,它创建一个外观,您的 Xaml 可以透明地绑定(bind)到该外观。如图所示,每个公开的属性都简单地回显了传输私有(private)实例中的值。更改通过 INotifyPropertyChanged 接口(interface)中继到 WPF 绑定(bind)引擎。
要创建一个实例,您可以使用原始传输类构造它。要绑定(bind)这些容器的集合,您可以声明一个传输容器类型的 ObservableCollection。这样做意味着除了属性中的各种更改之外,列表也是绑定(bind)的。
在这种方法中,您的“扩展”属性只是另一个没有 setter 的公开属性。请注意,影响状态的其他成员的更改代表“扩展”属性调用通知。在传输类的其余成员中编码应该需要大约 20 分钟......
关于c# - 是否可以将数据绑定(bind)到扩展方法?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/17735376/