【问题标题】:WPF How do I evaluate a property to make bindingWPF 如何评估属性以进行绑定
【发布时间】:2015-07-30 00:18:06
【问题描述】:

我正在为我们公司做一个自定义控件,我想将元素的 DataTemplate 定义到 ResourceDictionary 中,以获得更多的通用性和皮肤处理。 我的控件有一个 ItemsSource 属性,其中包含所有集合。我的控件中还有一个 DependencyProperty,它指定要绑定的当前项的属性名称。

一些代码:

<DataTemplate x:Key="VEGA_TokenTemplate">
  <Border x:Name="Bd" BorderBrush="{StaticResource VEGA_TokenBorderBrush}" BorderThickness="1" Background="{StaticResource VEGA_TokenBackgroundBrush}" Padding="1" Margin="1,5" HorizontalAlignment="Stretch" SnapsToDevicePixels="True">
    <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
      <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="20" />
      </Grid.ColumnDefinitions>
      <TextBlock Text="{Binding WHAT_HERE}" HorizontalAlignment="Stretch" VerticalAlignment="Center" />
      <Button Background="Transparent" Content="X" VerticalAlignment="Center" HorizontalAlignment="Center" FontSize="10" FontFamily="Berlin Sans FB" Grid.Column="1" Command="{Binding RelativeSource={RelativeSource AncestorType=local:TokenTextBox}, Path=TokenDeleteButtonCommand}"
      CommandParameter="{Binding WHAT_HERE}" IsEnabled="True" />
    </Grid>
  </Border>
</DataTemplate>

在这个 DataTemplate 中,我想通过评估我的依赖属性来替换 WHAT_HERE 标记。 例如,如果我在我的依赖属性上设置“Email”,我希望 Binding 类似于“Path=Email”。但是,我的组件中只有“电子邮件”作为文字。我该如何做这样的绑定?

我希望我的解释清楚......

谢谢

【问题讨论】:

  • 如果你放置“.”它将采用绑定的当前上下文,因此如果您将其绑定到自定义对象/类,然后覆盖 ToString() 方法以返回您希望它显示的内容,但是如果您绑定到属性,那么它将使用该值你过去了。
  • 是的,它会起作用,但如果我的 ToString 显示另一件事,我想在这里进行“动态反射绑定”。;...
  • 你能详细说明ToString()显示的另一件事吗?
  • 例如:MyMailAddress 类,toString 返回:“FROM :” + 电子邮件(当然这只是一个例子,但如果我只需要电子邮件呢)
  • 如果可以避免这样做,即返回“FROM email@sample.com”并只使用电子邮件,否则您想对无效数据使用动态绑定。为避免使用它,您可以使用Converter 并将字符串附加一些其他文本,或使用其他控件,如TextBlock。如果我在您使用绑定传递参数时没有弄错,它将使用底层对象而不是将其转换为字符串。试一试:-)

标签: c# wpf binding datatemplate


【解决方案1】:

我会在这种情况下使用行为或附加属性。我相信你可以通过其他方式来实现这一点。但这里有一种方法可以给你一个想法

//test interface and test class
public interface IProvidePropertyToBindTo
{
    string GetPropertyToBindTo();
}

public class TestChoosingPropertyToBind : IProvidePropertyToBindTo, INotifyPropertyChanged
{
    #region Fields
    public event PropertyChangedEventHandler PropertyChanged;
    private string _emailAddress;
    private string _name;
    private string _propertyName;
    #endregion Fields
    #region Properties
    public string EmailAddress
    {
        get { return _emailAddress; }
        set
        {
            if (_emailAddress == value) 
                return;
            _emailAddress = value;
            OnPropertyChanged();
        }
    }
    public string Name
    {
        get { return _name; }
        set
        {
            if (_name == value)
                return;
            _name = value;
            OnPropertyChanged();
        }
    }

    public string PropertyToBindTo
    {
        set { SetPropertToBindTo(value); }
    }

    #endregion 

    #region Methods
    public string GetPropertyToBindTo()
    {
        return _propertyName;
    }

    public void SetPropertToBindTo(string propertyName)
    {
        var prop = GetType().GetProperty(propertyName);
        if (prop == null)
            throw new Exception("Property : "+propertyName+" does not exist in this object {"+this.ToString()+"}.");
        _propertyName = propertyName;
    }



    [NotifyPropertyChangedInvocator]
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }
    #endregion Methods
}

测试数据

public ObservableCollection<TestChoosingPropertyToBind> Test
    {
        get
        {
            return new ObservableCollection<TestChoosingPropertyToBind>(
                new List<TestChoosingPropertyToBind>()
                {
                    new TestChoosingPropertyToBind(){EmailAddress = "Test@test.com", PropertyToBindTo = "EmailAddress"},
                    new TestChoosingPropertyToBind(){Name = "Test", PropertyToBindTo = "Name"}
                }
                );
        }
    }

具有自定义行为的数据模板的已编辑 sn-p

<DataTemplate x:Key="VEGA_TokenTemplate">
        <Border x:Name="Bd" BorderBrush="Red" BorderThickness="1" Background="White" Padding="1" Margin="1,5" HorizontalAlignment="Stretch" SnapsToDevicePixels="True">
            <Grid VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="20" />
                </Grid.ColumnDefinitions>
                <TextBlock Text="{Binding WHAT_HERE}" HorizontalAlignment="Stretch" VerticalAlignment="Center" >
                    <i:Interaction.Behaviors>
                        <BehaviorLocationNamespace:MyCustomBehavior></BehaviorLocationNamespace:MyCustomBehavior>
                    </i:Interaction.Behaviors>
                </TextBlock>
                <Button Background="Transparent" 
                        Content="X" 
                        VerticalAlignment="Center" 
                        HorizontalAlignment="Center" 
                        FontSize="10" FontFamily="Berlin Sans FB" Grid.Column="1"  IsEnabled="True" />
            </Grid>
        </Border>
    </DataTemplate>

//Items Control usage
<ItemsControl ItemTemplate="{StaticResource VEGA_TokenTemplate}" ItemsSource="{Binding Test}">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-13
    • 1970-01-01
    • 2015-03-11
    • 2011-02-04
    • 2015-04-01
    • 2013-01-14
    • 1970-01-01
    • 2011-04-22
    相关资源
    最近更新 更多