2

私はWPFを始めていますが、データバインディングの実装に少し苦労しています。

具体的には、ラベルとボタンを保持する単純なユーザーコントロールを作成しました。このユーザーコントロール用に、string「Text」とSimpleEnum「Status」の2つのプロパティのみを保持するViewModelを作成しました。

コントロールのポイントは、「接続済み」はい/いいえなどのステータスを表示することです。ボタンの背景色はステータスを示します。

私のXAMLは次のようになります

<Control.DataContext>
    <vm:OnOffStatusViewModel />
</Control.DataContext>

<Label x:Name="label1" Height="Auto" HorizontalAlignment="Left" Content="{Binding Text}" Width="280" />
<Button Style="{StaticResource GlassButton}" Height="14" Width="14" Background="{Binding Status}" Grid.Column="1" />

xmlns:vm="clr-namespace:Controls"

コードビハインドにはViewModel、ビューモデルを公開し、INotifyPropertyChangedを実装し、次のように初期化するプロパティがあります。_viewModel = (OnOffStatusViewModel) DataContext;

これで、このコントロールを使用しているビューでは、テキストを何かに設定できました。これは、ビューのコードビハインドを実装している場合と同じですがonOffStatus1.ViewModel.Text = ...、ステータスは列挙型によって設定されるため、実際にはバインドできません。ボタンのbackgroundプロパティ。

これに関連する私の質問:

  1. 私がコントロールを行った方法は正しいですか?そうでない場合、ユーザーコントロールにデータバインディングを実装する適切な方法は何ですか?

  2. バインディングを使用して列挙型ステータスでボタンのbackgroundプロパティを更新するにはどうすればよいですか?

4

3 に答える 3

2

バインディングを使用してボタンの背景プロパティを列挙型ステータスで更新するにはどうすればよいですか?

このタスクには値コンバーターを使用して、列挙型のすべての可能な値に対してブラシを返すことをお勧めします。このように、ビュー モデルは色やブラシについて何も知る必要がなく、ステータスを視覚化したい場合はいつでもコンバーターを使用できます。

XAML

<UserControl x:Class="WpfApplication1.UserControl1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApplication1">

    <UserControl.Resources>
        <local:StatusColorConverter x:Key="StatusColorConverter" />
    </UserControl.Resources>

    <Button Background="{Binding Status, Converter={StaticResource StatusColorConverter}" />

</UserControl>

コンバータ

public enum Status
{
  Connected
}

public class StatusColorConverter : IValueConverter
{
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    switch ((Status)value)
    {
      case Status.Connected: return new SolidColorBrush(Colors.Green);
    }

    return new SolidColorBrush(Colors.Black);
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    throw new NotImplementedException();
  }
}

私がコントロールを行った方法は正しいですか?そうでない場合、ユーザー コントロールにデータ バインディングを実装する適切な方法は何ですか?

あなたの実装は私には問題ないようです。ビュー モデルとビュー (現在、ビュー モデルへの参照を保持している) の間の結合を、依存性注入によって排除したい場合があります。ただし、これはユースケースと使用するアーキテクチャによって異なります。

于 2012-06-18T19:59:22.950 に答える
1

ここでの他の回答とは少し異なるアプローチを取ります。コードとロジックをビューモデルに直接配置したいので、次のようにします。

<Control.DataContext>
    <vm:OnOffStatusViewModel />
</Control.DataContext>

<Label x:Name="label1" Height="Auto" HorizontalAlignment="Left" Content="{Binding Text}" Width="280" />
<Button Style="{StaticResource GlassButton}" Height="14" Width="14" Background="{Binding ButtonBg}" Grid.Column="1" />

VMの場合:

public MyStatus Status
{
   get { return _status; }
   set
   {
      _status = value;
      OnPropertyChanged("Status");

      ButtonBg = Colors.Red;
   }    
}

public Color ButtonBg 
{
   get { ... }
   set { ... }
}

ボタンの背景はビューモデルのプロパティにバインドされているため、ロジックやコードをコンバーターやテンプレートに移動することなく、ビューモデルで何が起こっているかに応じてボタンの背景を自由に変更できます。

于 2012-06-18T20:17:12.990 に答える
1

個人的には、MVVM でカスタム UserControls を使用できませんでした。それらを一緒に使用する方法について私の心がまとまっていないか、単に混ざり合っていないかのどちらかです. ウィンドウ以外のすべてに DataTemplates を使用します。

簡潔にまとめます...

OnOffStatusVM : INPC
   string Status
   Color Color (or Brush)
   (set Color when enum value updates)

(OnOffStatus DataTemplate)
<DataTemplate DataType="{x:Type ViewModel:OnOffStatusVM}" x:Shared="False" x:Key="rezOnOffStatus">
   <Grid>   
      <Label Height="Auto" HorizontalAlignment="Left" Content="{Binding Status}" Width="280" />
      <Button Style="{StaticResource GlassButton}" Height="14" Width="14" Background="{Binding Color}" Grid.Column="1" />
   </Grid>
</DataTemplate>

DataContext が OnOffStatusVM から派生する場合の使用法

<ContentPresenter Content="{Binding}" ContentTemplate="{StaticResource rezOnOffStatus}" />

DataContext にOnOffStatusVM OnOffStatusプロパティがある場合の使用法

<ContentPresenter Content="{Binding OnOffStatus}" ContentTemplate="{StaticResource rezOnOffStatus}" />

必要に応じて提供される説明..

于 2012-06-18T20:08:43.153 に答える