开发者

how to update a user control when event occurs in another user control?

开发者 https://www.devze.com 2023-01-17 06:09 出处:网络
in my window i have tree view and a text block. tree view is bound to a view model. tree nodes are bound to another view model. the tree view model provides a list of top level tree nodes, and the vie

in my window i have tree view and a text block. tree view is bound to a view model. tree nodes are bound to another view model. the tree view model provides a list of top level tree nodes, and the view model for tree nodes provides the list of node children. there is no notion of the currently selected node in the tree in my view models.

in the text block i want to display the value of a known property of the view model of the currently selected tree node.

my question is how is this done the right MVVM way? i would prefer to do it in XAML. should i add the property to the tree view model for the currently selected node and then simply bind the text block to this property? if so, how would i communicate to the tree view model the fact that the tree view has changed its current node?

or can i do it differenly? i do not know how...

EDIT: let me rephrase the question: how to set the text inside the text block to the Name property of the view model corresponding to the selected item when the view model's IsSelected开发者_开发问答 property becomes true?


Just bind to the SelectedItem on the TreeView element itself.

Here's a pretty simple example that uses an XmlDataProvider. The DataTemplate on the ContentPresenter is where the magic happens:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
  <Page.Resources>
    <XmlDataProvider x:Key="Data" XPath="Tree">
      <x:XData>
        <Tree xmlns="" Text="Test">
          <Node Text="Weapon">
            <Node Text="Sword">
              <Node Text="Longsword"/>
              <Node Text="Falchion"/>
              <Node Text="Claymore"/>
            </Node>
            <Node Text="Polearm">
              <Node Text="Halberd"/>
              <Node Text="Pike"/>
            </Node>
          </Node>
          <Node Text="Armor">
            <Node Text="Cloth Armor"/>
            <Node Text="Leather Armor"/>
            <Node Text="Ring Mail"/>
            <Node Text="Plate Mail"/>
          </Node>
          <Node Text="Shield">
            <Node Text="Buckler"/>
            <Node Text="Tower Shield"/>
          </Node>
        </Tree>
      </x:XData>
    </XmlDataProvider>
    <HierarchicalDataTemplate x:Key="NodeTemplate" ItemsSource="{Binding XPath=Node}">
      <TextBlock Text="{Binding XPath=@Text}"/>
    </HierarchicalDataTemplate>
  </Page.Resources>
  <DockPanel>  
    <TreeView 
      x:Name="Objects" 
      ItemsSource="{Binding Source={StaticResource Data}, XPath=Node}"
      ItemTemplate="{StaticResource NodeTemplate}"/>
    <ContentPresenter Content="{Binding ElementName=Objects, Path=SelectedItem}">
      <ContentPresenter.ContentTemplate>
        <DataTemplate>
          <TextBlock Text="{Binding XPath=@Text}"/>
        </DataTemplate>
      </ContentPresenter.ContentTemplate>
    </ContentPresenter>
  </DockPanel>
</Page>


You could use MVVM Light Messaging, which makes it a breeze to communicate between viewmodels, in a decoupled fashion.

Nice example here: http://chriskoenig.net/2010/07/05/mvvm-light-messaging/

MVVM Light Toolkit can be downloaded here: http://mvvmlight.codeplex.com/

0

精彩评论

暂无评论...
验证码 换一张
取 消