【问题标题】:overriding ToString() method, behaves strange with Binding覆盖 ToString() 方法,与 Binding 的行为很奇怪
【发布时间】:2016-09-28 06:00:54
【问题描述】:

见下文XAML:

<Window x:Class="TabControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
    xmlns:local="clr-namespace:TabControl"
    Title="MainWindow"   Height="300" Width="300"        
    xmlns:Interact="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"       
    DataContext="{Binding RelativeSource={RelativeSource Mode=Self}}"       
    >   
<Window.Resources>
    <Style TargetType="{x:Type DataGridRow}" x:Key="myStyle">
        <Style.Triggers>
            <DataTrigger Binding="{Binding IsTrend.Value}" Value="True" >
                <Setter Property="Background" Value="Gold"/>
            </DataTrigger>
        </Style.Triggers>            
    </Style>
</Window.Resources>
<ScrollViewer>
    <DataGrid ItemsSource="{Binding list}" x:Name="myGrid" RowStyle="{StaticResource myStyle}"  >
        <DataGrid.Columns>
            <DataGridTextColumn Header="Name" Binding="{Binding Path=Name.Value,Mode=TwoWay}" />               
        </DataGrid.Columns>                       
    </DataGrid>
</ScrollViewer>

DataGrid的来源

private ObservableCollection<dynamic> GetDynamicOrders2()
{
    var retVal = new ObservableCollection<dynamic>();
    for (int i = 0; i < 50; i++)
    {
        dynamic eo = new ExpandoObject();
        eo.Name = new CellContent("Order" + i);
        eo.IsTrend = new CellContent(i % 2 == 0);               
        retVal.Add(eo);
    }
    return retVal;
}

public sealed class CellContent : INotifyPropertyChanged
{
    private object _value;
    public object Value
    {
        get { return _value; }
        set
        {                
            _value = value;
            OnPropertyChanged("Value");               
        }
    }

    public CellContent(object value)
    {
        Value = value;            
    }             

    public event PropertyChangedEventHandler PropertyChanged;                
    private void OnPropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

要从每个绑定中删除 .Value override ToString() 方法。

public override string ToString()
{
    return Value.ToString();
}

并且绑定更改为:

<DataGridTextColumn Header="Name" Binding="{Binding Path=Name,Mode=TwoWay}" />    

但是 DataTriggerColumn 绑定的行为不同。有人可以解释为什么以及如何?为什么更改后DataTrigger 不起作用?

【问题讨论】:

  • 您能详细解释一下“从我覆盖ToString() 方法的每个绑定中删除.Value 吗?双向绑定显然无法将string值转换回来。
  • 我唯一能想到的是,如果 ToString 抛出异常是因为 Value 为 null 或者 Value 的 ToString 实现抛出异常。您应该在输出窗口中有信息
  • 不要使用ToString 来做这样的事情,正如已经提到的,你也会破坏双向绑定。
  • @Sinatr 你可能是对的,但我更关心为什么 Binding 和 Datatrigger 的行为不同......?在发布问题时...
  • @nkoniishvt 不,它不是......当一个对象在绑定中定义时,如果它是,它将被解析为原始类型,否则它将在应用 ToString() 方法后解析......和这就是为什么我覆盖了该方法并且很好奇没有得到预期的结果

标签: c# wpf xaml data-binding datatrigger


【解决方案1】:
<DataGridTextColumn Header="Name" Binding="{Binding Path=Name,Mode=TwoWay}" />  

DataGridTextColumn 采用 CellContent 实例并调用 ToString() 来显示它。它显示Value,但在路径中没有.Value,则不会应用数据网格单元格中的编辑。

<DataTrigger Binding="{Binding IsTrend}" Value="True" >

DataTrigger 接受CellContent 实例并使用参数"True" 调用Equals()。但是 CellContent 对象不等于"True"

如果我覆盖 Equals,DataTrigger 工作

public override bool Equals(object obj)
{
    return Value.ToString() == (string) obj;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    • 1970-01-01
    • 2021-06-09
    • 1970-01-01
    • 1970-01-01
    • 2018-01-10
    • 2018-07-05
    相关资源
    最近更新 更多