MVVM WPFパターンに関する依存関係プロパティを持つカスタムコントロールを作成できますか?MVVM WPFアーキテクチャでカスタムUserControlを作成する方法
はいの場合、別のMVVMアプリケーションでCustomControlをどのように使用して、依存関係のプロパティを公開しますか?
EDIT:私は「TestCustomControl」という名前の別のWPFアプリケーションでそれを使用し、その後customControlを作成することを可能にする簡単な例以下
。 しかし、依存関係のプロパティは私のために全く機能しません。
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
}
}
NB: "list.txtには"「.. \に置かれたファイルですTestCustomControl \ bin \ Debug "
誰かが私の依存関係プロパティが機能しない理由を見つけるのを手助けできますか?
UserControlまたはカスタムコントロールは、データバインディングをサポートするために、常に依存プロパティを公開します。ただし、これはアプリケーションのアーキテクチャとはまったく関係ありません。 MVVMかどうかは、UserControlコードには関係ありません。注意すべきことは、典型的なUserControlは独自のビューモデルを定義すべきではないことです。特に、独自のDataContextを明示的に設定するべきではありません。代わりに、親コントロールまたはウィンドウからDataContextを継承する必要があります。 – Clemens
再利用可能なコントロールは、UIのみであり、独自のビューモデルを持つべきではありません。 TextBoxにTextBoxViewModelがない様に。 DependencyPropertiesとして必要なものだけを公開し、コードをコードビハインドに置き、任意のタイプのWPFアプリケーションでそのコントロールを使用できます。 – Will
@Willこれは '文字列'にしか束縛されない 'Textbox'のような単純なものの良いアドバイスのようです。しかし、複雑なやネストされたプロパティを持つ 'User'クラスのような複雑なものを編集するためのユーザコントロールはどうでしょうか?確かに 'User'のユーザコントロールは' User'のインスタンスにバインドされます。 'User'はコントロールのView Modelと見なされませんか?いくつかの点で、 'string'は' Textbox'のためのView Modelです。 –