使用数据绑定处理样式

时间:2016-04-19 10:42:30

标签: c# .net wpf listview datatemplate

重写

我有一个接收文件的应用程序。此文件包含大量可编辑内容。此内容有多种可能的类型(即布尔复选框,文本框等)。问题是,这些值可以是单独的,也可以是组(最多8个),因此它们可以是数组。我们将这些值绑定到ListView,并使用DataTemplates来显示它们。实际上,我从数组列表中创建了ListView

这些数组中的项需要正确绑定数据并设置样式(例如,布尔数组需要创建复选框,而字符串数组需要文本框)。每个创建的元素都需要放在ListView的列中。当前样式使用DataTemplates进行数据绑定,即

<DataTemplate x:Key="testTemplate2">
    <TextBlock Text="{Binding Path=Value[0]}" 
               Margin="2" 
               HorizontalAlignment="Center" 
               VerticalAlignment="Center" />
</DataTemplate>

对输入数组中的每个值重复此操作,因此您有Value[1]Value[2]等。

这意味着重复几乎相同的代码8次,然后对下一种类型执行相同的操作。由于存在大量输入类型,这意味着重复的代码数量过多。

我的问题是:有没有更好的方法来做到这一点,所以我们不必重复数据模板,同时继续使用列?

顺便说一句,我使用的是.NET 3.5。

行的外观示例。每个元素都在自己的列中。组合框是从阵列构建的。 Example of what I want.

修改 示例DataTemplate:

<DataTemplate x:Key="textBoxTemplate2">
    <TextBox Text="{Binding Path=Value[2], NotifyOnSourceUpdated=True, UpdateSourceTrigger=PropertyChanged}" 
                     BorderBrush="{DynamicResource ComboBorder}"
                     Tag="{Binding Path=AllowedChars}"
                     PreviewTextInput="PreviewTextInputHandler"
                     DataObject.Pasting="PastingHandler"
                     ToolTip="{Binding Path=Title}" 
                     Margin="2" 
                     SourceUpdated="BindingSourceUpdated"
                     MaxLength="{Binding Path=DataLength}"
                     HorizontalAlignment="Stretch" 
                     VerticalAlignment="Center" >
        <TextBox.IsEnabled>
            <MultiBinding Converter="{StaticResource isEnabledConverter}">
                <Binding Path="IsLocked" Mode="OneWay" />
                <Binding Path="IsVisible[2]" Mode="OneWay" />
            </MultiBinding>
        </TextBox.IsEnabled>
    </TextBox>
</DataTemplate>

示例图:

Diagram

我有一个ViewModel。此ViewModel具有List,由ItemData组成。 ItemDataData有一个名为Values的数组。 List已绑定到View。我们需要根据我们要访问的ItemData的属性选择要使用的DataTemplate:

  1. 一个名称
  2. 选项arrray中的一个或多个。
  3. 目前,我们在ListView中显示List。生成ListView时,列的DataTemplates附加CellTemplate,每个索引一个,总共8个DataTemplates。

1 个答案:

答案 0 :(得分:1)

我的答案专注于你的话:由于存在大量的输入类型,这意味着重复的代码数量过多。

代码重用:

由于您Item template需要为不同的DataTypes定义不同类型的控件,因此代码无法完全缩减。我的意思是,如果您希望TextBox类型为StringCheckbox类型为Bool,则代码无法明显减少。但是,您可以减少的是一次又一次地为不同的Binding定义template语法,正如我在TextBox Template示例中看到的那样。您可以定义Biniding一次,然后使用n号(在您的情况下为8)控件中重复使用它们。以下是您的操作方法:

public class BindingResourceExtension : StaticResourceExtension
{
    public BindingResourceExtension() : base() { }

    public BindingResourceExtension(object resourceKey) : base(resourceKey) { }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var binding = base.ProvideValue(serviceProvider) as BindingBase;
        if (binding != null)
            return binding.ProvideValue(serviceProvider);
        else
            return null; //or throw an exception
    }
}

<强> XAML

<Window.Resources>
    <ResourceDictionary>
        <Binding x:Key="MyBinding" Path="MyProperty" Mode="TwoWay" />
    </ResourceDictionary>
</Window.Resources>

(...)

<TextBox Text="{ns:BindingResource MyBinding}" />
<CheckBox IsChecked="{ns:BindingResource MyBinding}" />

因此可以实现一些代码重用(使用大而复杂的bindings代码进行映像)。在您发布问题后,我正在搜索此类内容,因此我发布了另一个question for binding reuse并且它有所帮助。此外,当Bindings集中时,它们将很容易更新。

<强> ItemTemplate中:

除了你的代码重用问题,你可以使用嵌套的ItemsControl作为查看你的类digram我可以看到并在另一个答案中提出:

<ListBox ItemsSource="{Binding CollectionOfArrays}">
<ListBox.ItemTemplate>
    <DataTemplate>
        <ItemsControl ItemsSource="{Binding Array}" />
    </DataTemplate>
</ListBox.ItemTemplate>

现在对于内部ItemsControl,您必须实际定义Templates,但我认为您已经明确了这一部分。