0

So I want to have multiple tabs with a usercontrol in it, depending on how many items there are in a list. so I think this shoudn t be too hard but .... I start with a new window to make a tabcontroller and bind its itemsource(of the tabcontroler to the list):

<Window x:Class="xxxxx.extraforms.frmownedchamps"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               xmlns:sp="clr-xxxxx.usercontrols.ucoptions"
        Title="frmownedchamps" Height="593" Width="350" Loaded="Window_Loaded_1" ResizeMode="NoResize" WindowStyle="None" ShowInTaskbar="False">
    <Grid>
        <TabControl Name="thetabcontrol">
            <TabControl.ItemTemplate>
                <DataTemplate>

                    <StackPanel>
                        <Label  Content="{Binding name}" />
                    </StackPanel>

                </DataTemplate>
            </TabControl.ItemTemplate>

            <TabControl.ContentTemplate>
                <DataTemplate DataType="{x:Type sp:ucownedchampviewer}" >
                    <sp:ucownedchampviewer strname="{Binding Path=name}" strcode="{Binding Path=code}" clclist="{Binding Path=list}" teller="{Binding Path=teller}"  />
                </DataTemplate>
            </TabControl.ContentTemplate>
        </TabControl>

    </Grid>
</Window>

once the window get loaded it only does thetabcontrol.ItemsSource = settings.clclist;

the clclist is this:

     public static List<clc> clclist { get; set; }

    public void methodblabla()
    {
     foreach( xml blabla)
    {
    clc clctemp = new clc(xmlname, xmlcode);
    clclist.Add(clctemp);
    }
    }

the clc class is:

 public class clc
        {
            private static int counter = 0;
            public int teller { get; set; }
            public String name { get; set; }
            public String code { get; set; }
            public ObservableCollection<champion> list { get; set; }
            public clc(String name, String code)
            {

                this.name = name;
                this.code = code;
                teller = counter;
                counter++;
                makelist();
            }
            public void makelist()
            {
                var bytes = Convert.FromBase64String(code);
                var values = new System.Collections.BitArray(bytes);
                list = new ObservableCollection<champion>();
                int aantal = champions.list.Count;
                int teller = 0;
                int counter = 0;
                for (int x = aantal; x != 0; x--)
                {
                    if (values[x - 1] == true)
                    {
                        list.Add(champions.getchampbyid(counter + 1));
                        teller++;
                    }
                    counter++;
                }
            }
        }  

my usercontrol:

<UserControl x:Class="xxxxx.usercontrols.ucoptions.ucownedchampviewer"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:sp="clr-namespace:xxxxx"
             mc:Ignorable="d" 
             d:DesignHeight="564" d:DesignWidth="350" Loaded="UserControl_Loaded">
    <Grid Height="624">
        <Grid.Resources>
            <Style x:Key="Ownedstyle" TargetType="{x:Type ListViewItem}">
                <Setter Property="Background" Value="Red"></Setter>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding strowned}" Value="Yes">
                        <Setter Property="Background" Value="Green"></Setter>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </Grid.Resources>
            <StackPanel Margin="0,0,0,12">
            <StackPanel Orientation="Horizontal" Margin="5">
                <TextBox Name="txtclc" Width="250" Margin="2" Text="{Binding Path=strcode ,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" />
                <Button Name="btnload" Content="Save" Click="btnsave_Click" Width="55" Margin="2"/>
            </StackPanel>
            <Line Margin="2" />
            <StackPanel Orientation="Horizontal" Margin="5" HorizontalAlignment="Stretch" Width="350">
                <TextBlock VerticalAlignment="Center">Filter:</TextBlock>
                <TextBox Name="txtfilter" Height="30" Grid.Column="0" TextChanged="txtfilter_TextChanged" Margin="5" Width="250" />
                <Label Name="lblaantal"></Label>
            </StackPanel>
            <ListView Name="lsvallchamps"  Grid.Column="0" Grid.Row="1" Grid.RowSpan="1" Height="410" Width="auto" ItemContainerStyle="{StaticResource Ownedstyle}" ItemsSource="{Binding Path=clclist ,RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}" >
                <ListView.View>
                    <GridView>
                        <GridViewColumn Width="60">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="50" Source="{Binding image}" Stretch="Fill"></Image>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Width="120" DisplayMemberBinding="{Binding name}">
                            <GridViewColumnHeader Content="name" Tag="name" Click="SortClick"/>
                        </GridViewColumn>
                        <GridViewColumn Width="130" DisplayMemberBinding="{Binding strroles}">
                            <GridViewColumnHeader Content="strroles" Tag="strroles" Click="SortClick" />
                        </GridViewColumn>
                    </GridView>
                </ListView.View>
            </ListView>
            <Button Content="testknop" Click="Button_Click" />
            <Button Content="Hide" Name="btnhide" Width="150" Height="35" Margin="5" Click="btnhide_Click"></Button>
        </StackPanel>
    </Grid>
</UserControl>

Sorry for so much code, but mayby better too much then too less code. The problem is that I want the button btnsave to save the txtclc.text to the code and make a new list of it, (and then the listview should be automaticly changed according to it since it is binded to it) However once I use the code

   private void btnsave_Click(object sender, RoutedEventArgs e)
        {
            settings.clclist[teller].code = txtclc.Text;
            settings.clclist[teller].makelist();
        }

It does change it! I can see it with debug.writeline that the value has changed in the clclist. BUT the listview in this tab doesn t change! ONLY if I go to an other tab, then back to the first one then it has changed with the right champions. There even is a 2nd problem. O But if I go to an other tab(usercontrol) the txtclc.text is changed as well to the first one! also the list is not updated on the usercontrol, on neither! however the makelist method should change it? Sorry for this LONG question however I ve been googeling alot and no luck for this problem.

SOLUTION:

Replace Text="{Binding Path=strcode ,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" with Text="{Binding Path=code}" in the usercontrol. and add INotifyPropertyChanged to the clc class, Thx to Rachel!

Maximc
  • 1,722
  • 1
  • 23
  • 37

1 Answers1

2

You have two problems here.

The first, is that your classes don't implement INotifyPropertyChanged, so the UI has no idea that it's objects have changed. Make your clc class implement this interface, and raise the PropertyChanged event when the code and name properties change so the UI knows to update.

The second problem is that by default, WPF will re-use a template if possible. For example, your TabControl is creating one instance of your UserControl, and when you switch tabs it is simply changing the DataContext behind the UserControl. If txtclc.Text is not bound to something in the DataContext, then it will not change because you are viewing the exact same TextBox regardless of which tab you are viewing. The solution is to add a property to your DataContext object to store the Text of the txtclc TextBox, and bind the property.

Rachel
  • 130,264
  • 66
  • 304
  • 490
  • Ty for this! I implented the INotifyPropertyChanged, now the UI is updating as it should! :) However for my 2nd problem which you also provided an answer for I can t figure out what you mean with: Add a property to my datacontext to store the text of txtclc. Do I have a Datacontext at all lol :p. I ll google now what you might mean but a little more information what I excatly have to do would be very sweet. However Thank you already! :) – Maximc Feb 22 '12 at 16:29
  • @Maximc In your case, the `DataContext` looks like it is an instance of object `clc`, so you'd add the property there. I recall writing a small example of how DataContext works somewhere.... let me see if I can find it. – Rachel Feb 22 '12 at 16:34
  • @Maximc Found it. Check out my answer [here](http://stackoverflow.com/a/7262322/302677) – Rachel Feb 22 '12 at 16:35
  • But I ain t I doing that already, I am saving it in the property String "code" in the clc class? that is how I am able to get the clccode in the textbox at the start(and yes for each tab the textbox.text is different (but only at the start once I insert othertext and save it to the clc class then it is all the same) ? Anyway I am ready your post there now I ll post if I "still" don t get it then :). – Maximc Feb 22 '12 at 16:39
  • @Maximc You're binding to a property on the `UserControl`, and since the `UserControl` is the same instance regardless of which tab you are on, the property remains the same. If you were to bind it to `DataContext.code` instead of `strcode`, you would get a different value because the `DataContext` changes when you change the Tab. – Rachel Feb 22 '12 at 16:46
  • oke I think I understand it. However how can I set the datacontext to the right one for each usercontrol? Add something like Datacontext={Binding self}" ^^? However I am googling how to do it might find it myself then I ll post. – Maximc Feb 22 '12 at 17:28
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/8081/discussion-between-rachel-and-maximc) – Rachel Feb 22 '12 at 17:40