【问题标题】:Handling styling with data binding使用数据绑定处理样式
【发布时间】:2016-04-19 10:42:29
【问题描述】:

改写

我有一个接收文件的应用程序。该文件有大量可编辑内容。此内容有多种可能的类型(即布尔复选框、文本框等)。问题是,这些值可以是单独的,也可以是一组(最多 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。

行的外观示例。每个元素将在其自己的列中。组合框是从数组构建的。

编辑 示例数据模板:

<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>

示例图:

我有一个 ViewModel。这个 ViewModel 有一个 List,由 ItemData 组成。类 ItemData 有一个名为 Values 的数组。列表绑定到视图。我们需要根据要访问的 ItemData 的属性来选择要使用的 DataTemplate:

  1. 一个名字
  2. Options 数组一个或多个。

目前,我们在 ListView 中显示列表。生成ListView 时,各列有不同的DataTemplates 附加到它们的CellTemplates,每个索引一个,总共8 个DataTemplate。

【问题讨论】:

  • 使用带有ItemsSource={Binding Values}的ItemsControl?
  • 我就是这个意思。
  • @MKII 你能给出你定义的其他一些数据模板的代码吗,我想看看它们有多复杂/可能有多复杂?
  • @KyloRen 添加了其中一个数据模板的示例。这可能是第二个最复杂的。
  • @MKII 刚刚发布了针对您使用不同控件的代码重用问题的答案。我认为您现在已经清楚了值 [8] 将如何在 UI 上转换(通过在 ItemTemplate 中为列表框的每个项目使用 Itemscontrol,然后将您的模板用于内部 itemscontrol)。所以从答案中省略了那部分。

标签: c# .net wpf listview datatemplate


【解决方案1】:

我的回答集中在你的话上:由于输入类型很多,这意味着大量的重复代码。

代码重用:

由于您在Item template 中需要为不同的DataTypes 定义不同类型的控件,因此无法完全减少代码。我的意思是,如果您希望 TextBox 用于 String 类型或 Checkbox 用于 Bool 类型,则代码不能明显减少。但是,您可以减少的是为不同的template 一次又一次地定义Binding 语法,正如我在您的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 将集中化,因此它们很容易更新。

项目模板:

除了您的代码重用问题之外,您还可以使用嵌套的ItemsControl,因为通过查看您的类图,我可以看到并在另一个答案中提出建议:

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

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-29
    • 1970-01-01
    相关资源
    最近更新 更多