【问题标题】:Windows Phone 8.1 Listview value mappingWindows Phone 8.1 Listview 值映射
【发布时间】:2015-12-20 11:30:46
【问题描述】:

我在 XAML 页面中有一个 Listview 控件,它的 ItemSource 绑定到后面代码中的集合。

集合中绑定到每个 ListView 项的绑定数据模型有一个整数字段,可以包含值 0 或 1。

我将此字段绑定到 ListView 的 ItemTemplate 中的 TextBlock,因此在 ListView 中我看到包含文本 0 或 1 的行。

我的目标是在不更改 ItemSource 本身的情况下,在 ListView 中看到“sometext1”而不是 0 和“sometext2”而不是 1。

我看到的问题是:

  1. TextBlock 控件似乎无法从代码中覆盖以创建自定义 TextBlock,我可以在其中以编程方式更改值。

  2. 如果我改用 TextBox 控件,我可以更改值,但是当显示大量数据时程序会变慢并且它也不会显示更改的值。 (在调试模式下,我可以看到该文本属性具有新值,但屏幕上的 TextBox 为空。)

【问题讨论】:

  • 添加示例代码,并提及您已经尝试过的所有内容。
  • 我试图解释的是我不能使用 TextBox 控件,因为它太慢了。因此,我想在运行时以编程方式更改 TextBlock 控件的 Text 值,其中 TextBlock 具有来自其 itemsource 的其他绑定值。我没有示例代码,因为我不能这样做。我试图编写自定义 TextBlock 控件来做到这一点,但我不能这样做。在我看来,我不能从 TextBlock 类继承自己的控制权。
  • 您将哪个字段绑定到 textBlock(“我将此字段绑定到 xaml 网格中的 TextBlock 控件。所以在列表视图中,我看到第 0 行和第 1 行。我的目标是看到“sometext1”而不是 0 和“sometext2”而不是列表视图中的 1,而不更改 ItemSource。”)
  • 你可以使用转换器吗?还有文本块与列表视图有什么关系?

标签: c# xaml listview data-binding windows-phone-8.1


【解决方案1】:

如果您以“Windows”方式进行操作,那么这就是为 Windows 平台开发真正最容易的地方。这涉及利用 XAML 表示框架中内置的强大功能,如绑定和转换器!

我将忽略数据来自数据库,因为它可能来自网络或以编程方式创建,这无关紧要,最重要的是它存在于内存中的某个地方。

假设您的数据有一个模型类:

class Data
{
    public int intField { get; set; }
    public string otherField { get; set; }
}

在带有列表视图的页面后面的代码中,数据对象的集合:

private ObservableCollection<Data> ListViewData = new ObservableCollection<Data>();

然后我们可以将您的 ListView 数据绑定到 XAML 页面中的此集合,就像我假设您已经完成的那样:

<ListView ItemsSource="{Binding ListViewData}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <StackPanel Orientation="Vertical">
                <TextBlock x:Name="tbIntField" Text="{Binding intField, Mode=OneWay}"/>
                <TextBlock x:Name="tbOtherField" Text="{Binding otherField, Mode=OneWay}"/>
            </StackPanel>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

正如您所观察到的,此时 intField TextBlock 的内容将是 intField 的数值,这不是您想要的。因此,我们将使用转换器根据 intField 的值格式化 TextBlock 内容。

首先,在你的项目中新建一个类,我称之为intFieldConverter,它实现了IValueConverter接口:

class intFieldConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var intField = (int)value;
        switch (intField)
        {
            case 0:
                return "Foo";
            case 1:
                return "Bar";
            default:
                return default(string);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

所有这一切都是获取输入的 int 值并根据值返回要显示的字符串。我没有实现将其转换回来的方法,但这只是相同但倒退;如果您需要双向绑定,您可以这样做。

我们现在需要告诉您的 XAML 这个转换器。如果需要,将转换器命名空间添加到 XAML 页面:

<Page
    ....
    xmlns:converters="using:BindingTest.UI.Converter"
    ....>

然后我们需要在 Page 标签内的转换器命名空间中指定 Converter 资源:

<Page.Resources>
    <converters:intFieldConverter x:Key="customIntToStringConverter"/>
</Page.Resources>

我们现在可以在 TextBlock 绑定中使用它来转换值并在视图中显示正确的字符串:

<TextBox x:Name="tbIntField" Text="{Binding intField, Mode=OneWay, Converter={StaticResource customIntToStringConverter}}"/>

如果您的代码隐藏的可观察集合中填充了一些数据,您现在应该会看到列表视图中的每一行现在将根据数据中 intField 的值显示“Foo”或“Bar”。

希望对你有帮助

注意:

我没有运行任何代码来测试它,因为我目前没有一台机器可以和我一起测试它。我可以检查我什么时候回到家,仔细检查你之前是否无法让它工作。

【讨论】:

  • 优秀。正是我想要的。非常感谢您的快速帮助!
  • 我还有一个与此相关的问题:好吧,我将 TextBlock 的值更改为编译时已知的值或通过常量 sql 表达式获得的值。但是我在 xaml 中有描述符对象,例如将 sql 表达式绑定到 TextBlocks,sql 的结果会给我要更改的值。所以在转换器函数中我会知道,哪个 TextBlock 的值正在改变以决定必须运行哪个 sql 表达式。
  • 好的,我大概找到了答案:我需要使用 ConverterParameter。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-03
相关资源
最近更新 更多