WPF数据绑定问题

时间:2011-01-11 15:29:38

标签: c# wpf .net-4.0 binding

我是WPF的新手,当我尝试使用自定义对象列表填充ListView时,我遇到了一些困难。

internal class ApplicationCode
{
    public int Code { get; set; }

    public IEnumerable<string> InstrumentCodes { get; set; }
}

我有一个ApplicationCode列表,我将ItemsSource设置为ListView。我需要将ApplicationCode.Code显示为字符串,并为其余列显示一个复选框,可以根据InstrumentCodes集合中是否包含列名来检查/取消选中该复选框。

为了设置复选框,我在数据绑定上使用转换器:

<DataTemplate x:Key="InstrumentCodeTemplate">
  <CheckBox IsEnabled="False" IsChecked="{Binding Mode=OneTime, Converter={StaticResource InstrumentSelectionConverter}}" />
</DataTemplate>

我遇到的问题是因为我无法知道在单元数据绑定时哪个是当前列,我无法设置ConverterParameter。

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
  ApplicationCode appCode = value as ApplicationCode;

  return appCode != null && appCode.InstrumentCodes.Contains(parameter.ToString());
}

小例子:

    Id  | Code1 | Code3 | Code4
--------------------------------
    123 |  True | False | True

第1行的数据:ApplicationCode.InstrumentCodes {Code1,Code4}

有一种方法可以找出列索引或名称吗?或者有另一种方法来解决这个问题?

2 个答案:

答案 0 :(得分:1)

列名应该只是一个视觉;这意味着所需的数据都应该驻留在底层对象模型中。因此,每行数据都是一个对象。

也许对代码进行重组就足够了,这也可以消除对转换器的需求......请记住,这是一个实现这个想法的例子,需要修改才能实际使用。

    internal class ApplicationCode
    {
        private CodeService _codeService = new CodeService();

        public int Code { get; set; }
        public bool IsValidCode
        {
            get
            {
                return _codeService.DoesIntrumentCodeExist(Code.ToString());
            }
        }
    }

    internal class CodeService
    {
        private IEnumerable<string> _instrumentCodes;

        public CodeService()
        {
            //instantiate this in another way perhaps via DI....
            _instrumentCodes = new List<string>();
        }

        public bool DoesIntrumentCodeExist(String instrumentCode)
        {
            foreach (String code in _instrumentCodes)
            {
                if (code == instrumentCode)
                    return true;
            }

            return false;
        }
    }

答案 1 :(得分:0)

到目前为止我得到的解决方案是动态添加列并在每列上设置ConverterParameter。

foreach (var instrument in instruments)
{
    var column = new GridViewColumn
                        {
                            HeaderTemplate = GetColumnHeaderTemplate(instrument),
                            CellTemplate = GetColumnCellTemplate(instrument),
                            Header = instrument,
                        };

    view.Columns.Add(column);
}

private static DataTemplate GetColumnCellTemplate(string instrument)
{
    var binding = new Binding
    {
        ConverterParameter = instrument,
        Converter = new InstrumentSelectionConverter(),
        Mode = BindingMode.OneWay
    };

    var template = new DataTemplate();
    template.VisualTree = new FrameworkElementFactory(typeof(CheckBox));
    template.VisualTree.SetBinding(ToggleButton.IsCheckedProperty, binding);

    return template;
}

我知道这不是最好的解决方案,如果有人能直接从.xaml向我展示一种方法,我真的很感激。