【问题标题】:WPF - Bind a textbox's content other TextboxWPF - 将文本框的内容绑定到其他文本框
【发布时间】:2017-04-17 05:35:26
【问题描述】:

我有两个在 wpf mvvm 中独立工作的文本框。但是现在我想根据一个复选框将一个文本框的输入绑定到另一个文本框。

  <Label Grid.Row="4" Grid.Column="0" Style="{StaticResource StlLblForm}" Margin="0,5">First Name:</Label>
  <TextBox Grid.Row="4" MaxLength="10" Grid.Column="1" Style="{StaticResource StlTxtForm}" Text="{Binding FirstName}" Grid.ColumnSpan="2" Margin="0,1,0,11" />

  <Label  Grid.Row="5" Grid.Column="0" Style="{StaticResource StlLblForm}" Margin="0,5">Last Name:</Label>
  <TextBox Grid.Row="5" Grid.Column="1" Style="{StaticResource StlTxtForm}" Text="{Binding LastName}" AcceptsReturn="True" Grid.ColumnSpan="2" Margin="0,1,0,11" />
  <CheckBox Content="CopyFirstNameToLast" />

所以当我选中复选框时,它会将名字复制到姓氏。我可以在没有代码的情况下做到这一点吗?如果是那怎么办?

【问题讨论】:

  • 您需要onproperty更改通知
  • 在 XAML 中将姓氏绑定到名字很简单,请参阅stackoverflow.com/questions/9586956/… 了解更多信息。但是复选框使它变得更加复杂,您可能必须编写一个值转换器来完成这项工作。
  • 您为什么希望避免代码落后?您可以使用自定义转换器,但您的场景的代码隐藏将是正确的方法恕我直言。

标签: c# wpf mvvm


【解决方案1】:

无代码:

 <Label>First Name:</Label>
 <TextBox x:Name="txtFirstName" Width="100" MaxLength="10" Text="{Binding FirstName}" />
<Label >Last Name:</Label>
  <TextBox Width="100">
     <TextBox.Style>
                <Style TargetType="TextBox">
                    <Setter Property="Text" Value="{Binding LastName}" />
                    <Style.Triggers>
                        <DataTrigger Binding="{Binding ElementName=chk, Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Value="True">
                            <Setter Property="Text" Value="{Binding ElementName=txtFirstName, Path=Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
                        </DataTrigger>
                    </Style.Triggers>
                </Style>
            </TextBox.Style>
        </TextBox>
        <CheckBox x:Name="chk" Content="CopyFirstNameToLast" />

【讨论】:

  • 就像一个魅力。太感谢了。这就是我一直在寻找的:)
【解决方案2】:

当您遵循 MVVM 模式来实现您的应用程序时,您应该注意到根据MVVM pattern guide,视图应该包含任何应用程序逻辑:

视图负责定义结构、布局和 用户在屏幕上看到的外观。理想情况下,视图是 纯粹使用 XAML 定义,具有有限的代码隐藏 包含业务逻辑。

FirstName 复制到LastName 应用程序逻辑的一部分,因此您应该将此任务委托给您的 ViewModel。

再次引用 MSDN:

视图模型充当视图和模型之间的中介, 并负责处理视图逻辑。

这正是您想要实现的目标。

所以为了保持整洁,您应该在 ViewModel 中定义 FirstNameLastName 属性,这些属性将绑定到 View 的 TextBoxes,就像您在问题代码中所做的那样:

// ViewModel
public const string FirstNamePropertyName = "FirstName";
private string _firstName = null;
public string FirstName
{
    get
    {
        return _firstName;
    }

    set
    {
        _firstName = value;
        RaisePropertyChanged(FirstNamePropertyName);
    }
}

public const string LastNamePropertyName = "LastName";
private string _lastName = null;
public string LastName
{
    get
    {
        return _lastName;
    }

    set
    {
        _lastName = value;
        RaisePropertyChanged(LastNamePropertyName);
    }
}

<!-- XAML -->

<Label Grid.Row="4" Grid.Column="0" Style="{StaticResource StlLblForm}" Margin="0,5">First Name:</Label>
<TextBox Grid.Row="4" MaxLength="10" Grid.Column="1" Style="{StaticResource StlTxtForm}" Text="{Binding FirstName}" Grid.ColumnSpan="2" Margin="0,1,0,11" />

<Label  Grid.Row="5" Grid.Column="0" Style="{StaticResource StlLblForm}" Margin="0,5">Last Name:</Label>
<TextBox Grid.Row="5" Grid.Column="1" Style="{StaticResource StlTxtForm}" Text="{Binding LastName}" AcceptsReturn="True" Grid.ColumnSpan="2" Margin="0,1,0,11" />

虽然 CheckBox 可以通过两种方式处理:

  • 您将其Checked 事件绑定到 ViewModel 的命令 操作您的 FirstNameLastName 属性,然后将复选框的 IsChecked 属性值作为命令参数传递给它(硬方式)
  • 您将IsChecked 属性绑定到 ViewModel 的布尔属性和 在 setter 中处理你的逻辑(简单的方法)

所以要做到这一点很简单:

// ViewModel
public const string CheckedPropertyName = "Checked";
private bool _checked = false;
public bool Checked
{
    get
    {
        return _checked;
    }

    set
    {
        _checked = value;
        RaisePropertyChanged(CheckedPropertyName);

        // app logic is handled here
        if (_checked)
        {
            LastName = FirstName;
        }
    }
}

<!-- XAML -->
<CheckBox IsChecked="{Binding Checked}" />

【讨论】:

猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 2011-07-17
  • 2012-11-23
  • 2016-02-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-24
相关资源
最近更新 更多