3

您好以下建议
您有一个 DataContext 是的文本块:

  • 这个[0]
  • 这个[1]
  • 这个[...]
  • 这个[n]

此文本块是 DatagridCell 的子项

现在我想根据列位置设置一个绑定

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

要得到一个 this[...] 我需要像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; }
    }
}
4

1 回答 1

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:

如您所见,我在 Resources 中有 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 继承并放置一个可绑定的属性,该属性将用作参数。

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

你怎么看这个?

于 2013-10-29T09:24:03.010 回答