【问题标题】:Set Property in Viewmodel from Code Behind从后面的代码中设置 Viewmodel 中的属性
【发布时间】:2015-07-28 13:23:32
【问题描述】:

我认为我在这一点上想多了,但我有一个独特的情况。

使用树视图我正在显示一个表格和该表格中的字段:

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>

示例:

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

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 事件是我抓取所选字段和表格的位置。如您所见,然后我在另一个视图模型中调用了一个方法,但这不会像我想要的那样工作,因为它会创建一个新实例。我只是把它放在那里基本上表明我想要做什么。总而言之,我需要能够在未连接到视图的视图模型中使用代码中的字段。

如果您需要更多信息或希望查看更多代码,请告诉我。提前致谢!

【问题讨论】:

    标签: c# wpf xaml mvvm treeview


    【解决方案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);
                }
            }
    

    【讨论】:

    • 我不知道我是否真的不应该在 MVVM 中这样做,但我什至不在乎哈哈。它进行了一些调整。非常感谢!
    【解决方案2】:

    您可以将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 从您的TreeView 绑定到DataContext.SomeViewModelCommand。

    CommandParameter 是绑定到DataTemplate 的Field。

    现在,您需要做的就是在您的视图模型 (SomeViewModelCommand) 中声明一个 Command,其中 Command Parameter 将是您的 Field。 p>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-30
      • 2020-09-27
      • 2012-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-11-26
      相关资源
      最近更新 更多