0

我有 ObservableCollection Fathers,其中包含属性 ObservableCollection Sons。我在TreeView设置它的DataContext属性时显示它。该Sons属性ListBox在每个父亲绑定到下显示为一个单选按钮ItemsSource

第一次将树视图的 DataContext 设置为父亲列表,一切正常。根据数据检查单选按钮。

现在,我将其设置TreeView.DataContext为 null - 这样数据就会消失。然后回到Fathers我第一次设置的原始 ObservableCollection。

现在由于某种原因,单选按钮停止与子对象同步。我更深入了,我看到子对象(绑定到单选按钮)中的 setter 由于某种原因被提升为 false。我猜想与绑定有关。

绑定后是否有任何缓存TreeView或 ObservableCollection 正在保存?我希望它像我第一次设置绑定时一样工作 - 它应该像它应该只有 getter 那样被调用。

谢谢。

这是我的树视图

    <UserControl x:Class="Tester.CTLMyTree"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="400">

    <Grid x:Name="LayoutRoot" Background="White">
        <Border Background="#FF919191" BorderThickness="1" CornerRadius="5"
                        HorizontalAlignment="Left"  VerticalAlignment="Top"
                        Padding="5" BorderBrush="Black" Height="207" Width="190">
            <Border.Resources>
                <sdk:HierarchicalDataTemplate x:Key="LayerListTemplate">
                    <StackPanel Orientation="Vertical"  Width="200" >
                        <TextBlock Text="Hello"/>

                        <ListBox x:Name="lstViews" ItemsSource="{Binding Sons}" BorderThickness="0" Width="200">
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <RadioButton Content="Check" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>                                    
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>

                    </StackPanel>
                </sdk:HierarchicalDataTemplate>
            </Border.Resources>

            <sdk:TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource LayerListTemplate}" x:Name="myTreeView" />
        </Border>
    </Grid>
</UserControl>

背后的对象

public class CCFather
    {
        public CCFather()
        {
            Sons = new ObservableCollection<CCSon>();
        }

        public ObservableCollection<CCSon> Sons
        {
            get;
            set;
        }
    }

    public class CCSon
    {
        private bool m_blnChecked;

        public bool IsChecked
        {
            get
            {
                return m_blnChecked;
            }
            set
            {
                m_blnChecked = value;
            }
        }
    }

在我的应用程序中,我添加了这个树视图控件并将其命名为 m_objSimpleTree。这段代码是初始化

m_objItems = new ObservableCollection<CCFather>();
CCFather objItem1 = new CCFather();
objItem1.Sons.Add(new CCSon());
objItem1.Sons[0].IsChecked = true;

m_objItems.Add(objItem1);

m_objSimpleTree.myTreeView.DataContext = m_objItems;

当我按下按钮时,我正在这样做

m_objSimpleTree.myTreeView.DataContext = null;
m_objSimpleTree.myTreeView.DataContext = m_objItems;

此代码已将儿子的 IsChecked 设置器提升为 false(为什么???)但仍将检查 RadioButton。第二次按下按钮。它将被取消选中,并且二传手没有加注。当我按下单选按钮时,它提高了二传手的两倍。第一次用假第二次用真。

不知道为什么会这样。我能想到的唯一想法是树视图在第一个绑定或类似的东西中保存了一些东西。

4

1 回答 1

0

这样做是因为您已经为控件使用了双向绑定

绑定代码项目

当您更改视图上的某些内容时,以两种方式绑定,然后数据也会保存在对象中。数据上下文被分配到的位置。尝试 oneWay 。但需要小心,就好像您想使用 twoWay 一种方式保存数据可能无济于事。MVVM 建议使用两种方式绑定来保存数据,但您需要刷新列表然后创建一个新对象 :)

也尝试清除绑定

清晰绑定

我不确定最后一个链接,因为从未尝试过。请通过它可能会有所了解。但是由于您可能再次需要一个新对象,因此您可以创建一个新对象以分配给数据上下文。

---编辑-----

这是一个xaml代码

<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" x:Class="SilverlightSOApp.MainPage"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
    <Border Background="#FF919191" BorderThickness="1" CornerRadius="5"
                    HorizontalAlignment="Left"  VerticalAlignment="Top"
                    Padding="5" BorderBrush="Black" Height="207" Width="190">
        <Border.Resources>
            <sdk:HierarchicalDataTemplate x:Key="LayerListTemplate">
                <StackPanel Orientation="Vertical"  Width="200" >
                    <TextBlock Text="Hello"/>

                    <ListBox x:Name="lstViews" ItemsSource="{Binding Sons}" BorderThickness="0" Width="200">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <StackPanel>
                                    <RadioButton Content="Check"  GroupName="abcd" IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
                                    <RadioButton Content="Check" GroupName="abcd" IsChecked="{Binding IsChecked2, Mode=TwoWay}"/>
                                </StackPanel>
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>

                </StackPanel>
            </sdk:HierarchicalDataTemplate>
        </Border.Resources>

        <sdk:TreeView ItemsSource="{Binding}" ItemTemplate="{StaticResource LayerListTemplate}" x:Name="myTreeView" />
    </Border>
    <Button Content="Button" HorizontalAlignment="Left" Margin="303,268,0,0" VerticalAlignment="Top" Width="75" Click="Button_Click"/>

</Grid>

和 C#

using System;

使用 System.Collections.Generic;使用 System.Collections.ObjectModel;使用 System.Linq;使用 System.Net;使用 System.Windows;使用 System.Windows.Browser;使用 System.Windows.Controls;使用 System.Windows.Documents;使用 System.Windows.Input;使用 System.Windows.Media;使用 System.Windows.Media.Animation;使用 System.Windows.Shapes;

命名空间 SilverlightSOApp { 公共部分类 MainPage : UserControl {

    private ObservableCollection<CCFather> m_objItems;

    public MainPage()
    {
        InitializeComponent();
        Loaded += new RoutedEventHandler(MainPage_Loaded);
    }
    void MainPage_Loaded(object sender, RoutedEventArgs e)
    {
        m_objItems = new ObservableCollection<CCFather>();
        CCFather objItem1 = new CCFather();
        objItem1.Sons.Add(new CCSon());
        objItem1.Sons[0].IsChecked = false;

        m_objItems.Add(objItem1);

        myTreeView.DataContext = m_objItems;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        myTreeView.DataContext = null;
        myTreeView.DataContext = m_objItems;
    }

}

public class CCFather
{
    public CCFather()
    {
        Sons = new ObservableCollection<CCSon>();
    }

    public ObservableCollection<CCSon> Sons
    {
        get;
        set;
    }
}

public class CCSon
{
    private bool m_blnChecked;
    private bool m_blnChecked2;

    public bool IsChecked
    {
        get
        {
            return m_blnChecked;
        }
        set
        {
            m_blnChecked = value;
        }
    }
    public bool IsChecked2
    {
        get
        {
            return m_blnChecked2;
        }
        set
        {
            m_blnChecked2 = value;
        }
    }
}

}

现在的要点是,如果您想为单个单选按钮实现它,那么您需要实现 Click 事件并将单选按钮设置为 false 并且下次设置为 true :) 否则您需要使用checkbox一个单选按钮,一旦选中就无法转换假的

于 2013-09-26T07:15:32.957 回答