如何在其中使用绑定绑定

时间:2013-10-29 07:34:13

标签: wpf xaml binding multibinding

嗨以下建议
你有一个DataContext的Textblock:

  • 此[0]
  • 此[1]
  • 此[...]
  • 此[n]的

此Textblock是DatagridCell的子级

现在我想基于列位置设置绑定

所以我写了Binding RelativeSource={RelativeSource FindAncestor,AncestorType=DataGridCell},Path=Column.DisplayIndex },工作正常

得到一个这个[...]我需要绑定像Binding Path=[0]这样也很好用

但是,如果我,但两者都像这样:

{ Binding Path=[ {Binding Path=Column.DisplayIndex, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell}} ] }

它没有绑定错误

System.Windows.Data Error: 40 : BindingExpression path error: '[]' property not found on 'object' ''List`1' (HashCode=33153114)'. BindingExpression:Path=[{Binding Path=Column.DisplayIndex, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell} }]; DataItem='List`1' (HashCode=33153114); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')

所以有人知道怎么做吗?


编辑:

这里简单的代码:

XAML

<DataGrid AutoGenerateColumns="true" Height="200" HorizontalAlignment="Left" Margin="243,12,0,0" Name="grid" VerticalAlignment="Top" Width="200"
          SelectionMode="Extended" SelectionUnit="Cell">
    <DataGrid.Resources>
        <Style TargetType="{x:Type DataGridCell}">
            <Setter Property="Background" Value="Green"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="DataGridCell">
                        <StackPanel >
                            <TextBlock Text="{Binding Path=Column.DisplayIndex, RelativeSource={RelativeSource FindAncestor, AncestorType=DataGridCell} }" />
                            <TextBlock Text="{Binding Path=[0] }" />
                        </StackPanel>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </DataGrid.Resources>
</DataGrid>

CS

/// <summary>
/// Interaktionslogik für MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();

        var gridList = new List<List<MyCell>>();

        for (int i = 0; i < 5; i++)
        {
            var cell1 = new MyCell { Text1 = "nr " + i, Text2 = "value1" };
            var cell2 = new MyCell { Text1 = "nr " + i, Text2 = "value2" };


            var sublist = new List<MyCell>();
            sublist.Add(cell1);
            sublist.Add(cell2);

            gridList.Add(sublist);
        }

        grid.ItemsSource = gridList;
    }
}

public class MyCell
{
    string value1;
    string value2;

    public string Text1
    {
        get { return value1; }
        set { value1 = value; }
    }
    public string Text2
    {
        get { return value2; }
        set { value2 = value; }
    }
}

1 个答案:

答案 0 :(得分:2)

你到那里有趣的灌输。

很有可能做你真正要求的事情。

Binding Path有一个名为PathParameters的属性,以下是如何使用它:

new Binding {
    Path = new PropertyPath("Values[(0)]", new DateTime(2011, 01, 01))
}

在此示例中,不是零,而是注入日期。

您可以在此处找到有关路径语法的信息:

http://msdn.microsoft.com/en-us/library/ms742451.aspx

编辑2:

破解wpf使其正常工作。

让我们说这是你的ViewModel。

public class VM
{
    private Dictionary<int, string> dic;

    public Dictionary<int, string> Dic
    {
        get
        {
            if (dic == null)
            {
                dic = new Dictionary<int, string>();
                dic[123] = "Hello";
            }

            return dic;
        }
    }

    public int Index
    {
        get
        {
            return 123;
        }
    }
}

这是XAML:

我在资源中有DataContext,你可以看到。

<Window x:Class="WpfApplication1.MainWindow"
        xmlns:helper="clr-namespace:WpfApplication1.Helper">
    <Window.Resources>
        <local:VM x:Key="viewModel"/>
    </Window.Resources>

    <StackPanel>
       <Button>
        <Button.Content>
            <helper:ParameterBinding Source="{StaticResource viewModel}" PropertyName="Dic" HasIndex="True">
                <helper:ParameterBinding.ParameterObject>
                    <helper:ParameterBindingHelperObject BindableParameter="{Binding Source={StaticResource viewModel}, Path=Index}"/>
                </helper:ParameterBinding.ParameterObject>
            </helper:ParameterBinding>
        </Button.Content>
      </Button>
    </StackPanel>
</Window>

这是一切的关键:

public class ParameterBinding : Binding
{
    private ParameterBindingHelperObject parameterObject;

    public ParameterBindingHelperObject ParameterObject
    {
        get
        {
            return parameterObject;
        }

        set
        {
            this.parameterObject = value;
            this.parameterObject.Binding = this;
        }
    }

    public bool HasIndex
    {
        get;
        set;
    }

    public string PropertyName
    {
        get;
        set;
    }

    public void UpdateBindingPath()
    {
        string path = this.PropertyName + (HasIndex ? "[" : "") + this.ParameterObject.BindableParameter + (HasIndex ? "]" : "");
        this.Path = new PropertyPath(path);
    }
}

public class ParameterBindingHelperObject : DependencyObject
{
    private ParameterBinding binding;

    public ParameterBinding Binding
    {
        get
        {
            return binding;
        }

        set
        {
            this.binding = value;
            this.binding.UpdateBindingPath();
        }
    }

    public object BindableParameter
    {
        get { return (object)GetValue(BindableParameterProperty); }
        set { SetValue(BindableParameterProperty, value); }
    }

    public static readonly DependencyProperty BindableParameterProperty =
        DependencyProperty.Register("BindableParameter", typeof(object), typeof(ParameterBindingHelperObject), new UIPropertyMetadata(null, PropertyChangedCallback));

    private static void PropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
    {
        ParameterBindingHelperObject obj = (ParameterBindingHelperObject)dependencyObject;
        if (obj.Binding != null)
        {
            obj.Binding.UpdateBindingPath();
        }
    }
}

我从Binding继承并放置一个可绑定属性,该属性将作为参数。

从技术上讲,你可以改变它并制作最棒的绑定。您可以允许在运行时更改索引号,路径将更改。

你怎么看待这个?