从Code Behind在Viewmodel中设置属性

时间:2015-07-28 13:23:32

标签: c# wpf xaml mvvm treeview

我认为我现在正在思考这个问题,但我有一个独特的情况。

使用treeview我正在显示一个表和该表中的字段:

XAML:

        <TreeView x:Name="myTreeView" PreviewMouseDoubleClick="myTreeView_MouseLeftButtonDown" SelectedValuePath="Name" ItemsSource="{Binding Fields}" ItemContainerStyle="{StaticResource TreeViewItemExpandedStyle}">
            <TreeView.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Fields}">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Foreground="Black" Text="{Binding Table}" />                               
                    </StackPanel>
                    <HierarchicalDataTemplate.ItemTemplate>
                        <DataTemplate>
                            <StackPanel Orientation="Horizontal">
                                <Button BorderBrush="Transparent"
                                        Background="White" 
                                        Command="">
                                    <StackPanel>
                                        <Path Margin="5" 
                                      Data="M0,5 H10 M5,5 V10Z" 
                                      Stroke="#2283B4" 
                                      StrokeThickness="1" 
                                      Height="10" 
                                      Width="10" />
                                    </StackPanel>
                                </Button>
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Text="{Binding Name}" />
                                    <TextBlock Height="0" Width="0" Visibility="Collapsed" Text="{Binding Table}"/>
                                </StackPanel>
                            </StackPanel>
                        </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
                    <!--<HierarchicalDataTemplate.Triggers>
                        <DataTrigger Binding="{Binding IsExpanded}" Value="True">
                            <Setter TargetName="treeIcon"
                                    Property="Data"
                                    Value="M0,5 H10"/>
                        </DataTrigger>
                    </HierarchicalDataTemplate.Triggers>-->
                </HierarchicalDataTemplate>
            </TreeView.ItemTemplate>

        </TreeView>

示例:TreeView

这些树视图也是他们自己的用户控件。我遇到的问题是我需要能够在另一个视图模型中使用选定的树视图项。除了后面的代码之外,我还没有找到其他方法来获取所选的treeview项和父项。以下是此控件的完整代码部分。

SourceRowUserControl.xaml.cs:

using Alliance.FromAnywhereControl.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Alliance.FromAnywhereControl.ViewModels;
using System.Reflection;

namespace Alliance.FromAnywhereControl
{
    /// <summary>
    /// Interaction logic for SourceRowUserControl.xaml
    /// </summary>
    public partial class SourceRowUserControl : UserControl
    {
        public SourceRowUserControl()
        {
            InitializeComponent();
        }

        private ObservableCollection<ConversionRowUserControl> ConversionTypes = new ObservableCollection<ConversionRowUserControl>();

        public ObservableCollection<TableInformation> Fields
        {
            get { return (ObservableCollection<TableInformation>)GetValue(FieldsProperty); }
            set { SetValue(FieldsProperty, value); }
        }

        // Using a DependencyProperty as the backing store for Fields.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FieldsProperty =
            DependencyProperty.Register("Fields", typeof(ObservableCollection<TableInformation>), typeof(SourceRowUserControl), new PropertyMetadata(TableInformation.GetAll(null, null, null, null)));


        public String FileTypeImage
        {
            get { return (String)GetValue(FileTypeImageProperty); }
            set { SetValue(FileTypeImageProperty, value); }
        }

        // Using a DependencyProperty as the backing store for FieldTypeImage.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty FileTypeImageProperty =
            DependencyProperty.Register("FileTypeImage", typeof(String), typeof(SourceRowUserControl), new PropertyMetadata("File Type Image"));

        public SolidColorBrush SpacerColor
        {
            get { return (SolidColorBrush)GetValue(SpacerColorProperty); }
            set { SetValue(SpacerColorProperty, value); }
        }

        // Using a DependencyProperty as the backing store for SpacerColor.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SpacerColorProperty =
            DependencyProperty.Register("SpacerColor", typeof(SolidColorBrush), typeof(SourceRowUserControl), new PropertyMetadata(new SolidColorBrush(Colors.Red)));


        public String MiddleLabel
        {
            get { return (String)GetValue(MiddleLabelProperty); }
            set { SetValue(MiddleLabelProperty, value); }
        }

        // Using a DependencyProperty as the backing store for MiddleLabel.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty MiddleLabelProperty =
            DependencyProperty.Register("MiddleLabel", typeof(String), typeof(SourceRowUserControl), new PropertyMetadata("Middle Label"));

        private void myTreeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {

                Field selectedField = new Field();

                selectedField = (Field)myTreeView.SelectedItem;

                ConversionViewModel cvm = new ConversionViewModel();

                cvm.AddConversionType(selectedField.Table, selectedField.Name);         
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

    }
}

myTreeViewLeftButtonDown事件是我抓取所选字段和表的位置。如你所见,我正在另一个viewmodel中调用一个方法,但是由于它创建了一个新实例,所以我不想这样做。我只是把它放在那里基本上显示我想要做的事情。概述,我需要能够在未连接到视图的视图模型中使用我的代码中的字段。

如果您需要更多信息或希望查看更多代码,请与我们联系。提前谢谢!

2 个答案:

答案 0 :(得分:1)

查看代码,而不是定义新的ConversionViewModel(),抓取ConversionViewModel的实例,然后在其上设置属性。

public class ConversionViewModel()
{
    private static ConversionViewModel _this;
    public ConversionViewModel()
        {
            InitializeComponent();
            _this = this;
        }

        public static ConversionViewModel GetInstance()
        {
            return _this;
        }

      //Other prop and methods
}

private void myTreeView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            try
            {

                Field selectedField = new Field();

                selectedField = (Field)myTreeView.SelectedItem;

               ConversionViewModel.GetInstance().AddConversionType(selectedField.Table, selectedField.Name);                       
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

答案 1 :(得分:0)

您可以将ItemTemplate InputBinding提供给左键单击操作。

<DataTemplate>
    <StackPanel Orientation="Horizontal">
        <StackPanel.InputBindings>
            <MouseBinding MouseAction="LeftClick"
                          Command="{Binding DataContext.SomeViewModelCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=TreeView}}"
                          CommandParameter="{Binding}"/>
        </StackPanel.InputBindings>
        ...
    </StackPanel>
</DataTemplate>

为了帮助解释这一点,MouseBinding指定LeftClick上发生StackPanel时要执行的命令。

Command与您DataContext.SomeViewModelCommand的{​​{1}}绑定。

TreeView是绑定到CommandParameter的{​​{1}}。

现在,您需要做的就是在视图模型(Field)中声明命令,其中命令参数将是您的{{1} }。