簡體   English   中英

如何使用MVVM WPF體系結構創建自定義UserControl

[英]How to Create Custom UserControl with MVVM WPF architecture

是否可以使用依賴於MVVM WPF模式的依賴項屬性創建自定義控件?

如果是,那么如何在另一個MVVM應用程序中使用CustomControl並公開依賴項屬性?

編輯:

下面是一個允許我創建customControl的簡單示例,然后我在另一個名為“TestCustomControl”的WPF應用程序中使用它。 但是,依賴屬性對我來說根本不起作用。

在此輸入圖像描述

CustomControlView.xaml

<UserControl xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"  xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"  x:Class="MyCustomControl.MyCustomUserControl"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
         xmlns:myCustomControl="clr-namespace:MyCustomControl"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">

<dxmvvm:Interaction.Triggers>
    <dxmvvm:EventToCommand Command="{Binding LoadCommand}" EventName="Loaded" />
</dxmvvm:Interaction.Triggers>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <dxe:ButtonEdit Height="40" Grid.Row="0"/>
    <dxg:GridControl Grid.Row="1" ItemsSource="{Binding MyItems}" AutoGenerateColumns="AddNew"/>
</Grid>

CustomControlView.xaml.cs

using System.Windows;
using System.Windows.Controls;
namespace MyCustomControl
{
    /// <summary>
    /// Interaction logic for MyCustomUserControl.xaml
    /// </summary>
    public partial class MyCustomUserControl : UserControl
    {
        public MyCustomUserControl()
        {
            InitializeComponent();
            this.DataContext = new CustomControlViewModel(FilePath);
        }
        /// <summary>
        /// File Path 
        /// </summary>
        public static readonly DependencyProperty FilePathProperty = DependencyProperty.Register(
            "FilePath", typeof(string), typeof(MyCustomUserControl), new PropertyMetadata(string.Empty));
        public string FilePath
        {
            get { return (string)GetValue(FilePathProperty); }
            set
            {
                SetValue(FilePathProperty, value);
            }
        }
    }
}

CustomControlViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using DevExpress.Mvvm;
using DevExpress.Mvvm.DataAnnotations;
namespace MyCustomControl
{
    public class CustomControlViewModel:ViewModelBase
    {
        #region Fields
        private ObservableCollection<string> _myItems;
        private string _path;
        #endregion

        #region Constructors
        public CustomControlViewModel(string path)
        {
            _path = path;
        }
        #endregion

        #region Commands

        [Command]
        public void Load()
        {
            IEnumerable<string> allLinesText = new List<string>();
            try
            {
                allLinesText = File.ReadAllLines(_path).ToList();
            }
            catch (Exception e)
            {

                Console.WriteLine(e.ToString());
            }

            MyItems = new ObservableCollection<string>(allLinesText);
        }
        #endregion

        #region Properties
        public ObservableCollection<string> MyItems
        {
            get { return _myItems; }
            set { SetProperty(ref _myItems, value, () => MyItems); }
        }
        #endregion
    }
}

MainWindow.xaml

<Window xmlns:MyCustomControl="clr-namespace:MyCustomControl;assembly=MyCustomControl"  
    x:Class="TestCustomControl.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:testCustomControl="clr-namespace:TestCustomControl"
    Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
    <testCustomControl:MainViewModel/>
</Window.DataContext>
<Grid>
    <MyCustomControl:MyCustomUserControl FilePath="{Binding MyFile}"/>
</Grid>

MainViewModel.cs

using DevExpress.Mvvm;
namespace TestCustomControl
{
    public class MainViewModel: ViewModelBase
    {
        #region Fields
        private string _myFile;        
        #endregion

        #region Constructors
        public MainViewModel()
        {
            MyFile = "List.txt";
        }
        #endregion

        #region Properties
        public string MyFile
        {
            get { return _myFile; }
            set { SetProperty(ref _myFile, value, () => MyFile); }
        }
        #endregion
    }
}

注意: “List.txt”是放在“.. \\ TestCustomControl \\ bin \\ Debug”中的文件

有人可以幫我找到為什么我的依賴屬性不起作用?

這顯然是可能的,這是創建自定義控件的最佳方式。 因為沒有依賴屬性,我們無法輕松地重用自定義控件。 使用依賴屬性,可重用性變得非常容易。 您可以使用ICommand作為依賴項屬性,從而遵循MVVM模式並具有更清晰的代碼。

如果我詳細說明如何在另一個MVVM應用程序中重用CustomControl,那么它就太寬泛了,無法在這里得到解答。 你可以去Visual Studio並創建一個自定義控件。 在后面的代碼中定義了一些依賴屬性,這些屬性綁定到您認為是動態的屬性,在視圖中。 在另一個應用程序中重用這個非常自定義的控件,並在重用它時設置這些屬性。

您還可以嘗試使用ICommand將某些事件路由到視圖模型。 即,列表項選擇更改事件的依賴項屬性可以將命令路由到相應的視圖模型。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM