2012-08-06 178 views
0

我編寫了一個IIS web.config文件版本的程序。我在我的TreeView控件中遇到問題,它不想在源XmlDocument變量中更改某些內容後自行刷新。
這是WPF項目。在XAML更改後TreeView不刷新

窗口資源:

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

我的TreeView:

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

+0

調用'_xmlDataProvider.Refresh();'不會刷新您的文件,如果您從一個路徑加載它,但保存對'_tempFileName'的更改。您可能需要'saveChangesButton_Click()'仍然調用'OpenXmlFile()'。另外,設置'_xmlDataProvider.Document'會自動調用'_xmlDataProvider.Refresh()'(請參閱http://msdn.microsoft.com/zh-cn/library/system.windows.data.xmldataprovider.document.aspx) – 2012-08-06 15:43:39

回答

2

你好,你可以用結合雙向試穿你的TreeView和可觀察的集合。

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

Firslty你可以修改你的綁定

ItemsSource="{Binding Source={StaticResource XmlData}, XPath=*, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
+0

後悔,但它不適合我。我甚至試圖修改我的代碼,以便更適合你的建議,但它並沒有工作:/ – Nickon 2012-08-06 14:23:38

+0

對我來說,這是我的項目的工作,這是肯定模式二方式是爲這種情況,爲了有從源代碼控制或從源代碼控制綁定,這是很好的做法 – 2012-08-06 14:29:47

+0

嗯,所以現在我開始想知道我做的不好:/ – Nickon 2012-08-06 14:32:26

1

你只設定xmlDataProvider.Document值在OpenXmlFile()功能,如果它是空的。當您設置 _xml = new XmlDocument();時,它會將_xml設置爲指向新對象,但xmlDataProvider仍指向舊對象。然後,您有以下兩行:

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

如果你在這裏從RefreshViews()獲得,_xmlDataProvider.Document不會爲空,所以你永遠不會刷新與您的數據提供的XML文件。

+0

你能描述一下如何改變它嗎?如何將_xml的新實例綁定到數據提供者? – Nickon 2012-08-06 13:50:31

+0

我會建議擺脫空檢查,或者使用Aghilas的雙向約束建議。 – 2012-08-06 15:15:42

+0

我做了兩個,沒有對我有用:/ – Nickon 2012-08-07 07:06:24