1
votes

I have a Listview control in a XAML page which has it's ItemSource bound to a collection in the code behind.

The bound data model within the collection that is bound to each ListView item has one integer field which can contain the value 0 or 1.

I am binding this field to a TextBlock in the ItemTemplate of the ListView, and so in the ListView I am seeing rows containing the text 0 or 1.

My goal is to see "sometext1" instead of 0 and "sometext2" instead of 1 in the ListView without changing the ItemSource itself.

The problems I am seeing are:

  1. TextBlock controls seems to unable to override from code to create a custom TextBlock in which I can change values programatically.

  2. If I use TextBox control instead, I can change the values, but the program slows down when large amount of data is shown and it also not shown the changed values. (In debug mode I can see, that text property has the new value, but the TextBox is empty on screen.)

1
add sample code ,Also mention what all you have tried already.Nikita Shrivastava
What i try to explain is I cannot use TextBox control because its too slow. So I would like to change a TextBlock control's Text value programatically at runtime which TextBlock has an other binding value comes from its itemsource. I have no sample code, because i cannot do this. I tried to write custom TextBlock control to do it, but I cannot do that. It seems to me that i cannot inherit own control from TextBlock class.Developer Joe
which field did you bind to the textBlock ("I bind this field to a TextBlock control in xaml grid. So in the listview, i see rows 0 and 1. My goal is to see "sometext1" instead of 0 and "sometext2" instead of 1 in listview without changing the ItemSource.")Nikita Shrivastava
can you use converters? Also how is the textblock related to the listview?Nikita Shrivastava

1 Answers

0
votes

This is where developing for the Windows platform really is easiest if you do things in the "Windows" way. This involves taking advantage of the awesome functionality built into the XAML presentation framework like binding and converters!

I'm going to ignore that the data comes from a database, as it could come over the network or created programmatically and it shouldn't matter, bottom line is it exists in memory somewhere.

Assuming you have a model class for your data:

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

and in the code behind of your page with the listview, an collection of data objects:

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

We can then bind your ListView data to this collection in the XAML page as I'm assuming you have done:

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

As you have observed, at this point, the contents of the intField TextBlock will be the numeric value of the intField which isn't what you want. So we're going to use a converter to format the TextBlock contents based on the value of the intField.

First, create a new class in your project, I called it intFieldConverter which implements the IValueConverter interface:

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();
    }
}

All this does is takes the input int value and returns the string you want to show based on value. I didn't implement the method to convert it back but that's just the same but backwards; you can do that if you need two way binding.

We now need to tell your XAML about this converter. Add your converter namespace to your XAML page if you need it:

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

We then need to specify the Converter resource in that converters namespace inside the Page tag:

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

We can now use it in our TextBlock binding to convert the values and show the right string in the view:

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

If your codebehind has the observable collection populated with some data, you should now see each row in the listview will now show either "Foo" or "Bar" based upon the value of the intField in the data.

Hope this Helps

Note:

I haven't run any of this code to test it as I don't have a machine to test it on with me at the moment. I can check when I get home to double check if you haven't been able to get it working before.