0

我为 IIS web.config 文件的版本编写了一个程序。我的 TreeView 控件出现问题,在我更改源 XmlDocument 变量中的某些内容后不想刷新自身。
这是 WPF 项目。

XAML 中的窗口资源:

<Window.Resources>
   <XmlDataProvider x:Key="XmlData" />
</Window.Resources>

我的树视图:

<TreeView x:Name="XmlTree" Grid.Row="1"
   ItemsSource="{Binding Source={StaticResource XmlData}, XPath=*}"
   ItemTemplate="{StaticResource NodeTemplate}"
   SelectedItemChanged="XmlTree_SelectedItemChanged" />

树视图样式:

<DataTemplate x:Key="AttributeTemplate">
    <StackPanel Orientation="Horizontal"
            Margin="3,0,0,0"
            HorizontalAlignment="Center">
        <TextBlock Text="{Binding Path=Name}"
             Foreground="{StaticResource xmAttributeBrush}" FontFamily="Consolas" FontSize="8pt" />
        <TextBlock Text="=&quot;"
             Foreground="{StaticResource xmlMarkBrush}" FontFamily="Consolas" FontSize="8pt" />
        <TextBlock Text="{Binding Path=Value}"
             Foreground="{StaticResource xmlValueBrush}" FontFamily="Consolas" FontSize="8pt" />
        <TextBlock Text="&quot;"
             Foreground="{StaticResource xmlMarkBrush}" FontFamily="Consolas" FontSize="8pt" />
    </StackPanel>
</DataTemplate>

<HierarchicalDataTemplate x:Key="NodeTemplate">
    <StackPanel Orientation="Horizontal" Focusable="False">
        <TextBlock x:Name="tbName" Text="?" FontFamily="Consolas" FontSize="8pt" />
        <ItemsControl
            ItemTemplate="{StaticResource AttributeTemplate}"
            ItemsSource="{Binding Path=Attributes}"
            HorizontalAlignment="Center">
            <ItemsControl.ItemsPanel>
                <ItemsPanelTemplate>
                    <StackPanel Orientation="Horizontal"/>
                </ItemsPanelTemplate>
            </ItemsControl.ItemsPanel>
        </ItemsControl>
    </StackPanel>
    <HierarchicalDataTemplate.ItemsSource>
        <Binding XPath="*" />
    </HierarchicalDataTemplate.ItemsSource>
    <HierarchicalDataTemplate.Triggers>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Text">
            <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Value}"/>
        </DataTrigger>
        <DataTrigger Binding="{Binding Path=NodeType}" Value="Element">
            <Setter TargetName="tbName" Property="Text" Value="{Binding Path=Name}"/>
        </DataTrigger>
    </HierarchicalDataTemplate.Triggers>
</HierarchicalDataTemplate>

后面的代码:

private XmlDocument _xml;
private XmlElement _selectedElement; // actually selected item in TreeView
private XmlDataProvider _xmlDataProvider;
private string _tempFileName = @"C:\test.xml";

public MainWindow()
{
    InitializeComponent();

    XmlTree.Style = (Style)FindResource("TreeViewAllExpandedStyle");
    _xmlDataProvider = FindResource("XmlData") as XmlDataProvider;
}

private void OpenXmlFile(string filePath)
{
    XmlEditor.Clear(); // my text editor provided by AvalonEdit
    XmlEditor.Load(filePath);

    _xml = new XmlDocument();
    _xml.Load(filePath);

    if(_xmlDataProvider.Document == null)
        _xmlDataProvider.Document = _xml;
}

private void saveChangesButton_Click(object sender, EventArgs e)
{
    // some changes on _selectedElement (changes applies also into _xml)

    _xml.Save(_tempFileName);
    RefreshViews();
}

private void RefreshViews()
{
    // 
    OpenXmlFile(_tempFileName);

    // here I want to refresh my TreeView
    // I noticed that when I select back my changed item, its values are set, but in my tree I see the old ones...
    // I tried to do XmlTree.Focus() (nothing happens excepting control focus)
    // and _xmlDataProvider.Refresh() (here comes NullReferenceException)
    // I guess something bad happens in OpenXmlFile(...) method, because I reopen _xml and _xmlDataProvider looses a handler to it?
}

谁能解释为什么它不起作用?

[编辑]

我试图修改这样的2种方法:

private void OpenXmlFile(string filePath)
{
    XmlEditor.Clear();
    XmlEditor.Load(filePath);

    _xml = new XmlDocument();
    _xml.Load(filePath);

    _xmlDataProvider.Document = _xml;
}

private void saveChangesButton_Click(object sender, EventArgs e)
{
    // ...

    _xmlDataProvider.Document.Save(_tempFileName);
    _xmlDataProvider.Refresh();
}

现在我得到 NullReferenceException 而_xmlDataProvider.Refresh();

4

2 回答 2

2

您好,您可以尝试在 TreeView 和 observable 集合上使用双向绑定。

{Binding .... Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}

首先你可以修改你的绑定

ItemsSource="{Binding Source={StaticResource XmlData}, XPath=*, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
于 2012-08-06T13:24:46.133 回答
1

如果它是空的,你只是xmlDataProvider.Document在你的函数中设置它的值。OpenXmlFile()当您设置 _xml = new XmlDocument();时,它设置_xml为指向一个新对象,但xmlDataProvider仍指向旧对象。然后,您有以下两行:

if(_xmlDataProvider.Document == null)
    _xmlDataProvider.Document = _xml;

如果您从 , 进入这里RefreshViews()_xmlDataProvider.Document则不会为空,因此您永远不会刷新与您的数据提供者绑定的 XML 文件。

于 2012-08-06T13:27:38.827 回答