1

私のWindowsStoreアプリには、CueAnswerButtonユーザーコントロールがあります。{Binding NormalImage}これには、ビューモデルにバインドするImageコントロールが含まれています。ただし、CueAnswerButton内に他のコントロールとプロパティがあり、バインドされたプロパティが変更されるたびに更新する必要があります(CueAnswerButton内でコードが変更されるたびに実行したい)。

どうすればいいですか?

似たようなことを説明している他の記事を見つけましたが、完全ではありません。おそらく私は答えを見つけるために使用する正しい用語を知りません。

ご協力いただきありがとうございます。

// View data model for a cue answer button.

public class CueAnswerViewData : DependencyObject
{
  public CueAnswerViewData()
  {
  }

  public const string NormalImagePropertyTag = "NormalImageProperty";
  public static readonly DependencyProperty NormalImageProperty =
     DependencyProperty.Register(
         NormalImagePropertyTag,
         typeof(ImageSource),
         typeof(CueAnswerViewData),
         new PropertyMetadata(null));
  public ImageSource NormalImage
  {
    get
    {
      return (ImageSource)GetValue(
        NormalImageProperty);
    }
    set
    {
      SetValue(NormalImageProperty, value);
    }
  }

およびCueAnswerButton.xaml:

  <Grid>
    <Button x:Name="m_button" 
            HorizontalAlignment="Stretch" 
            VerticalAlignment="Stretch" 
            BorderThickness="0"
            />

    <Image x:Name="m_image" 
           HorizontalAlignment="Stretch" 
           VerticalAlignment="Stretch" 
           Stretch="Fill"
           Source="{Binding NormalImage}" 
           />

    ...

基本的に、ViewDataのNormalImageプロパティが変更されるたびに、CueAnswerButton.updateSkinnableProperties()を呼び出したいと思います。はい、これはwp7アプリの移植版です:)、まだ作業中です。

private void updateSkinnableProperties()
{
  bool skinned = isSkinned();

  m_image.IsHitTestVisible = skinned;
  m_button.IsHitTestVisible = !skinned;

  Background = m_correctHint ? m_correctAnswerGreenBrush : null;
  m_textbox.Background = m_correctHint ? m_correctAnswerGreenBrush : null;
  m_button.Background = m_correctHint ? m_correctAnswerGreenBrush : 
    m_phoneBackgroundBrush;

  m_button.BorderThickness = (skinned || m_correctHint) ?
    m_zeroThickness : m_phoneBorderThickness;

  m_textbox.Foreground = (skinned || m_correctHint) ?
    m_blackBrush : m_phoneForegroundBrush;

  m_button.Padding = skinned ?
    m_zeroThickness : m_phoneTouchTargetOverhang;

  if (!skinned)
  {
    m_button.Content = null;
  }

  updateSkinnableStateBasedProperties();
}

public bool isSkinned()
{
  bool skinned = false;

  if (m_normalImage != null && m_normalImage.ToString().Length > 0)
  {
    skinned = true;
  }

  return skinned;
}

private void updateSkinnableStateBasedProperties()
{
  if (!m_correctHint && isSkinned())
  {
    m_image.Visibility = Visibility.Visible;

    if (m_pressed && m_pressedImage != null)
    {
      m_image.Source = m_pressedImage;
    }
    else
    {
      m_image.Source = m_normalImage;
    }
  }
  else
  {
    m_image.Source = null;

    if(!m_correctHint)
    {
      m_textbox.Foreground = m_pressed ?
        m_phoneBackgroundBrush : m_phoneForegroundBrush;

      m_button.Background = m_pressed ?
        m_phoneForegroundBrush : m_phoneBackgroundBrush;
    }
  }
}
4

2 に答える 2

1

DependecyPropertyが値を変更するたびに呼び出されるデリゲートを追加できます...

  public static readonly DependencyProperty NormalImageProperty =
     DependencyProperty.Register(
         NormalImagePropertyTag,
         typeof(ImageSource),
         typeof(CueAnswerViewData),
         new PropertyMetadata(null, (s, e) =>
                var ctrl = s as CueAnswerViewData;
                if (ctrl != null) {
                   ctrl.somePropertyToUpdate = 123;
                }
            })
            );
于 2013-01-04T21:07:34.377 に答える
0

ジェフ・ブランドに+1を与えると、彼の答えが私の解決策を見つけるのに役立ちました。ただし、これを解決する最善の方法は、システムとの戦いをやめ、updateSkinnableProperties()ロジックをViewModel自体に移動し、INotifyPropertyChangedを実装することでした。公開されるプロパティの一部は、データ中心ではなくUI中心です(ブラシプロパティや厚さプロパティなど)が、最終的にはこれが最もクリーンで最良のソリューションでした。

ありがとう!

于 2013-01-08T00:09:22.753 に答える