绑定到单独的DataContext

时间:2011-08-16 08:00:37

标签: c# wpf

我有一个MainWindow,它包含一个带TreeView的窗口。树视图绑定到我在DataContext中设置的可观察集合。

                    <TreeView ItemsSource="{Binding Trees}"  Name="fileTree" MouseDoubleClick="FileTreeMouseDoubleClick" SelectedValuePath="NodePath">
                        <TreeView.Resources>
                        <HierarchicalDataTemplate DataType="{x:Type local:TreeNodeViewModel}" ItemsSource="{Binding Children}">
                            </HierarchicalDataTemplate>
                        </TreeView.Resources>
                    </TreeView>                        

但是,我想将一个单独的树作为MainWindow的子节点,它将绑定到另一个对象,如何使用DataContext MainWindow.xaml }?

编辑:问题扩展

现在我有:

<TreeView Name="viewTree" ItemsSource="{Binding ViewListTrees, Source=viewListTreeViewModel}">

其中viewListTreeViewModelMainWindow.xaml.cs中的成员变量:

private ViewListTreeViewModel viewListTreeViewModel;

具有以下访问者:

    public ObservableCollection<ViewListTreeNodeViewModel> ViewListTrees
    {
        get { return this.tree; }
    }

ViewListTreeNodeViewModel有:

    public string NodeName { get; }

    public string NodeImage { get; }

我的分层数据模板现在看起来像:

                            <HierarchicalDataTemplate DataType="{x:Type local:ViewListTreeNodeViewModel}" ItemsSource="{Binding Children}">
                                <StackPanel>
                                    <Image Source="{Binding NodeImage}" />
                                    <TextBlock Text="{Binding NodeName}"/>
                                </StackPanel>
                            </HierarchicalDataTemplate>

2 个答案:

答案 0 :(得分:2)

简单地在绑定到Window的类上公开两个属性(而不是直接绑定集合),公开ObservableCollection属性; TreesSeperateTree并相应地绑定每个TreeView:

<Window>
  <Grid>
    <TreeView ItemsSource="{Binding Trees}">
      ...
    </TreeView>
    <TreeView ItemsSource="{Binding SeperateTree}">
      ...
    </TreeView>
  </Grid>
</Window>

答案 1 :(得分:1)

您可以使用Source Binding部分直接绑定到对象,也可以DataContext本地设置另一个TreeView }。

示例1

<TreeView ItemsSource="{Binding Trees, Source=YourOtherDataContext}"/>  

示例2

<TreeView ItemsSource="{Binding Trees}" 
          DataContext="{Binding Path=YourOtherDataContext}"/>

正如评论中所承诺的,这是一个用于视图模型的基类示例。

<强>用法

public string Name
{
    get { return name; }
    set { SetValue(ref name, value, "Name"); }
}

<强> ObservableObject

public abstract class ObservableObject : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Compares the value and sets iff it has changed.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="field">The field.</param>
    /// <param name="value">The value.</param>
    /// <param name="propertyName">Name of the property.</param>
    /// <returns><c>True</c> if the field was changed</returns>
    protected virtual bool SetValue<T>(ref T field, T value, string propertyName)
    {
        return SetValue(ref field, value, propertyName, true);
    }

    /// <summary>
    /// Compares the value and sets iff it has changed.
    /// </summary>
    /// <param name="field">The field.</param>
    /// <param name="value">The value.</param>
    /// <param name="propertyName">Name of the property.</param>
    /// <param name="checkForEquality">if set to <c>true</c> [check for equality].</param>
    /// <returns><c>True</c> if the field was changed</returns>
    protected virtual bool SetValue<T>(ref T field, T value, string propertyName, bool checkForEquality)
    {
        if (checkForEquality && EqualityComparer<T>.Default.Equals(field, value))
            return false;

        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }

    /// <summary>
    /// Sets the value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="setAction">The set action.</param>
    /// <param name="propertyName">Name of the property.</param>
    /// <returns></returns>
    protected virtual bool SetValue(Action setAction, string propertyName)
    {
        return SetValue(setAction, null, propertyName);
    }

    /// <summary>
    /// Sets the value.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    /// <param name="setAction">The set action.</param>
    /// <param name="equalityFunc">The equality func.</param>
    /// <param name="propertyName">Name of the property.</param>
    /// <returns></returns>
    protected virtual bool SetValue(Action setAction, Func<bool> equalityFunc, string propertyName)
    {
        if (equalityFunc != null && !equalityFunc.Invoke())
            return false;

        setAction.Invoke();
        OnPropertyChanged(propertyName);
        return true;
    }

    protected void OnPropertyChanged(string propertyName)
    {
        OnPropertyChanged(this, propertyName);
    }

    protected void OnPropertyChanged(object source, string propertyName)
    {
        // copying the event handlers before that this is "thread safe"
        // http://blogs.msdn.com/b/ericlippert/archive/2009/04/29/events-and-races.aspx
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}