WPF

0
にメインウィンドウのViewModelにユーザーコントロールの依存プロパティをバインディング

私はその基本ブロックに問題を単純化することを許可します。WPF

私は私のプロジェクトでのUserControl1を持っています。

public string TextProperty 
{ 
    get { return (string)GetValue(TextPropertyProperty); } 
    set { SetValue(TextPropertyProperty, value); } 
} 

public static readonly DependencyProperty TextPropertyProperty = DependencyProperty.Register("TextProperty", typeof(string), typeof(UserControl1), new PropertyMetadata(null)); 

そしてユーザーコントロールのコンストラクタ単に

public UserControl1() 
{ 
    InitializeComponent(); 
    DataContext = this; 
} 

です:私はこのような依存関係プロパティを持って、コードビハインドで

<TextBox Text="{Binding TextProperty}"/> 

:それは、このようなテキストボックスを持っていますMainWindowでは、私はこれを持っています:

<userctrl:UserControl1 TextProperty="{Binding ABC, UpdateSourceTrigger=PropertyChanged}"/> 
<TextBox Grid.Row="1" Text="{Binding PQR, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/> 

さて、メインウィンドウのViewModelにに、私がしている:さて、でも、ユーザーコントロールは、右、私はテキストボックスに書くものは何でも複製することになっている

private string _abc; 
    public string ABC 
    { 
     get { return _abc; } 
     set 
     { _abc = "20"; 
      OnPropertyChanged(); 
     } 
    } 

    private string _pqr; 

    public string PQR 
    { 
     get { return _pqr; } 
     set 
     { 
      if(value != _pqr) 
      { 
       _pqr = value; 
       ABC = PQR; 
       OnPropertyChanged(); 
      } 
     } 
    } 

しかし、そうではありません。私はABCのセッターにブレークポイントを設定しました。更新されますが、その更新はUserControlに届きません。私の腸は、バインディングが黙って失敗していると言います。それは、DataContextthisに設定してあり、UserControlのコンストラクタにあります。

は、どのように私はそれを解決することが出来るのですか?

実際のシナリオ:

ここでは、ユーザーコントロールのためのXAMLである:ここで

<UserControl x:Class="MyDiskTools.UserControls.NodeGrid.NodeGrid" 
      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:local="clr-namespace:MyDiskTools.UserControls.NodeGrid"    
      mc:Ignorable="d"> 
    <Grid> 
     <Grid.Resources> 
      <Style TargetType="Button"> 
       <Setter Property="Padding" Value="5"/> 
       <Setter Property="BorderThickness" Value="1"/> 
       <Setter Property="Command" Value="{Binding InputCommand}"/> 
       <Setter Property="CommandParameter" Value="{Binding Path=Content, RelativeSource={RelativeSource Self}}"/>     
       <Style.Triggers>      
        <Trigger Property="IsMouseOver" Value="True"> 
         <Setter Property="BorderThickness" Value="5"/> 
         <Setter Property="FontSize" Value="20"/> 
         <Setter Property="FontFamily" Value="Times New Roman"/> 
        </Trigger>      
       </Style.Triggers> 
      </Style> 
     </Grid.Resources> 
     <Grid.RowDefinitions> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
      <RowDefinition></RowDefinition> 
     </Grid.RowDefinitions> 
     <UniformGrid Grid.Row="0" Rows="1"> 
      <Button Content="A" /> 
      <Button Content="B" /> 
      <Button Content="C" /> 
      <Button Content="D" /> 
      <Button Content="E" /> 
      <Button Content="F" /> 
     </UniformGrid> 
     <UniformGrid Grid.Row="1" Rows="1"> 
      <Button Content="G" /> 
      <Button Content="H" /> 
      <Button Content="I" /> 
      <Button Content="J" /> 
      <Button Content="K" /> 
      <Button Content="L" /> 
      <Button Content="M" /> 
     </UniformGrid> 
     <UniformGrid Grid.Row="2" Rows="1"> 
      <Button Content="N" /> 
      <Button Content="O" /> 
      <Button Content="P" /> 
      <Button Content="Q" /> 
      <Button Content="R" /> 
      <Button Content="S" /> 
      <Button Content="T" /> 
     </UniformGrid> 
     <UniformGrid Grid.Row="3" Rows="1"> 
      <Button Content="U" /> 
      <Button Content="V" /> 
      <Button Content="W" /> 
      <Button Content="X" /> 
      <Button Content="Y" /> 
      <Button Content="Z" /> 
     </UniformGrid> 
     <TextBox Name="InputMessage" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" IsEnabled="False" Background="Beige" Grid.Row="4" Text="{Binding PasswordDisplay, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 
    </Grid> 
</UserControl> 

は、コードビハインドである:

public partial class NodeGrid : UserControl 
{ 
    public NodeGrid() 
    { 
     InitializeComponent();    
     InputCommand = new InputCharacterCommand(this); 
     DataContext = this; 
    } 

    public string PasswordDisplay 
    { 
     get { return (string)GetValue(PasswordDisplayProperty); } 
     set { SetValue(PasswordDisplayProperty, value); } 
    } 


    public static readonly DependencyProperty PasswordDisplayProperty = 
     DependencyProperty.Register("PasswordDisplay", typeof(string), typeof(NodeGrid), new PropertyMetadata("")); 


    private ICommand _inputCommand; 

    public ICommand InputCommand 
    { 
     get 
     { 
      return _inputCommand; 
     } 

     set 
     { 
      _inputCommand = value; 
     } 
    } 


    public void AddCharacter(string input) 
    { 
     if (input != null) 
     { 
      PasswordDisplay = string.Concat(PasswordDisplay, input); 
     } 
    } 

    public bool InputAllowed() 
    { 
     if (PasswordDisplay == null) 
     { 
      return true; 
     } 

     if (PasswordDisplay.Length < 50) 
     { 
      return true; 
     } 

     return false; 
    } 

    private void OnPropertyChange([CallerMemberName] string property = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(property)); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

} 

class InputCharacterCommand : ICommand 
{ 
    private NodeGrid _vmodel; 

    public InputCharacterCommand(NodeGrid vm) 
    { 
     _vmodel = vm; 
    } 

    public event EventHandler CanExecuteChanged; 

    public bool CanExecute(object parameter) 
    { 
     return (_vmodel.InputAllowed()); 
    } 

    public void Execute(object parameter) 
    { 
     _vmodel.AddCharacter(parameter as string); 
    } 
} 

そして、ここでは、私はそれを使用する方法です

<StackPanel VerticalAlignment="Stretch" HorizontalAlignment="Stretch"> 
    <WrapPanel HorizontalAlignment="Center"> 
     <Label Content="Enter PIN"/> 
     <TextBox CommandManager.PreviewCanExecute="HandleCanExecute" Foreground="Transparent" MinWidth="100" Padding="10,0" Text="{Binding PIN, UpdateSourceTrigger=PropertyChanged}"/> 
    </WrapPanel> 
    <customlock:NodeGrid MinHeight="250" MinWidth="500" PasswordDisplay="{Binding NodeGridDisplay}"/> 
    <Button VerticalAlignment="Center" HorizontalAlignment="Center" Content="Unlock!"/> 
</StackPanel> 
:私のメインウィンドウで

コードビハインド:

private void HandleCanExecute(object sender, CanExecuteRoutedEventArgs e) 
{ 
    if (e.Command == ApplicationCommands.Cut || 
     e.Command == ApplicationCommands.Copy || 
     e.Command == ApplicationCommands.Paste) 
     { 
      e.CanExecute = false; 
      e.Handled = true; 
     } 

} 

そして今、ViewModelに:

private string _PIN; 

    public string PIN 
    { 
     get 
     { 
      return _PIN; 
     } 
     set 
     { 
      if(value != _PIN) 
      { 
       _PIN = value;      
       OnPropertyChanged(); 
       NodeGridDisplay = HashIt(_PIN); 
      } 
     } 
    } 

    private string _nodeGridDisplay; 

    public string NodeGridDisplay 
    { 
     get 
     { 
      return _nodeGridDisplay; 
     } 

     set 
     { 
      if (value != _nodeGridDisplay) 
      { 
       _nodeGridDisplay = value; 
       OnPropertyChanged(); 
      }     
     } 
    } 

    private string HashIt(string input) 
    { 
     using (System.Security.Cryptography.MD5 md5 = System.Security.Cryptography.MD5.Create()) 
     { 
      return System.Text.Encoding.Default.GetString(md5.ComputeHash(System.Text.Encoding.ASCII.GetBytes(input))).GetHashCode().ToString(); 
     } 
    } 

は、意図された機能は何ですか?

私はそれを説明しましょう。

The Lock

一つはPIN、NodeGridに表示されるのハッシュを入力することができます。次に、ユーザーはハッシュで連結される文字をクリックします。その後、ユーザーはロック解除をクリックできます。

答えて

1

UserControlElementNameを使用するか、RaltiveResourceを使用して見つけてください。DataContext = thisは使用しないでください。

は、ユーザーコントロールに名前を付け、書き込み(this answerthis linkを参照してください):

<UserControl x:Class= ...... 
     Name="userControl"> 
    <TextBox Text="{Binding Text, ElementName = userControl}"/> 
</UserControl> 

があなたの代わりにTextPropertyTextを使用して_abc = value_abc = "20"を変更することを確認する必要がありますのでご注意ください。

+0

申し訳ありません、 '_abc =" 20 "'。私はそれが一定の価値を持って働いているかどうかを見るために使っていました。 –

+0

私が与えた問題の説明があまりにも単純すぎたのかもしれません。私の状況は少し複雑です。私は自分の問題を説明するために質問を編集しました。 –

+0

あなたの単純な例と同じです。この部分で '' Text = "{Binding PasswordDisplay、Mode = TwoWay、UpdateSourceTrigger = PropertyChanged}" "' 'ElementName''を使用してください。他のことはうまくいくようです。 – Ron