【问题标题】:Usercontrol in datatemplate out of sync数据模板中的用户控件不同步
【发布时间】:2012-03-12 22:51:33
【问题描述】:

所以我希望有多个带有用户控件的选项卡,具体取决于列表中有多少项目。所以我认为这不应该太难但是....我从一个新窗口开始制作一个tabcontroller并将其itemsource(tabcontroler的列表)绑定:

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

一旦窗口被加载,它只会执行 tabcontrol.ItemsSource = settings.clclist;

clclist 是这样的:

     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++;
                }
            }
        }  

我的用户控件:

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

抱歉,代码太多了,但最好是太多代码而不是太少代码。问题是我希望按钮 btnsave 将 txtclc.text 保存到代码中并为其创建一个新列表,(然后列表视图应根据它自动更改,因为它已绑定到它) 但是一旦我使用了代码

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

它确实改变了它!我可以通过 debug.writeline 看到 clclist 中的值已更改。但是此选项卡中的列表视图不会改变!仅当我转到另一个选项卡,然后返回第一个选项卡时,它才会更改为正确的冠军。甚至还有第二个问题。 O 但是,如果我转到另一个选项卡(用户控件),则 txtclc.text 也会更改为第一个!用户控件上的列表也没有更新,也没有!但是makelist方法应该改变它吗? 很抱歉这个很长的问题,但是我一直在谷歌上搜索,但这个问题没有运气。

解决方案:

将用户控件中的 Text="{Binding Path=strcode ,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" 替换为 Text="{Binding Path=code}"。并将 INotifyPropertyChanged 添加到 clc 类,感谢 Rachel!

【问题讨论】:

    标签: c# wpf binding user-controls datatemplate


    【解决方案1】:

    这里有两个问题。

    首先,你的类没有实现INotifyPropertyChanged,所以用户界面不知道它的对象已经改变。让您的 clc 类实现此接口,并在 codename 属性发生更改时引发 PropertyChanged 事件,以便 UI 知道要更新。

    第二个问题是,默认情况下,WPF 会尽可能重用模板。例如,您的TabControl 正在创建您的UserControl 的一个实例,当您切换选项卡时,它只是更改了UserControl 后面的DataContext。如果txtclc.Text 未绑定到DataContext 中的某些内容,则它不会更改,因为您正在查看完全相同的TextBox,无论您正在查看哪个选项卡。解决方法是给你的DataContext对象添加一个属性来存储txtclcTextBox的Text,并绑定该属性。

    【讨论】:

    • 这个!我实现了 INotifyPropertyChanged,现在 UI 正在更新! :) 但是,对于我的第二个问题,您还提供了一个答案,因为我无法弄清楚您的意思:向我的数据上下文添加一个属性以存储 txtclc 的文本。我有一个数据上下文吗大声笑:p。我现在会用谷歌搜索你可能的意思,但我非常需要做的更多信息会非常甜蜜。不过已经谢谢你了! :)
    • @Maximc 在您的情况下,DataContext 看起来像是对象clc 的一个实例,因此您可以在其中添加该属性。我记得在某处写了一个 DataContext 如何工作的小例子……让我看看我能不能找到它。
    • @Maximc 找到了。看看我的回答here
    • 但我不是已经这样做了,我将它保存在 clc 类的属性字符串“代码”中?这就是我如何能够在开始时在文本框中获取clccode(是的,对于每个选项卡,textbox.text 都是不同的(但只有在我插入其他文本并将其保存到 clc 类时才开始,那么它就是全部相同) 无论如何我准备好你的帖子了,如果我“仍然”不明白,我会发帖:)。
    • @Maximc 您正在绑定到UserControl 上的属性,并且由于UserControl 是同一个实例,无论您在哪个选项卡上,该属性都保持不变。如果您要将其绑定到DataContext.code 而不是strcode,您将获得不同的值,因为DataContext 在您更改Tab 时会发生变化。
    猜你喜欢
    • 2022-01-07
    • 1970-01-01
    • 1970-01-01
    • 2020-05-12
    • 2013-05-28
    • 1970-01-01
    • 2018-06-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多