使用mvvm根据uwp中的combox选择更新文本框值

时间:2016-11-03 14:18:58

标签: mvvm uwp

我查看了一个组合框和五个文本框,用于添加新客户。要添加客户,请在我的viewmodel中声明属性,并将这些属性绑定到所有相应的文本框文本属性,例如

查看:

<StackPanel>
   <ComboBox ItemsSource="{Binding Customers}" SelectedItem="{Binding SelectedCustomers}" DisplayMemberPath="Name"/>
   <Textbox Text="{Binding Name}"/>
   <Textbox Text="{Binding Age}"/>
   <Textbox Text="{Binding Phone}"/>
   <Textbox Text="{Binding Address}"/>
   <Textbox Text="{Binding Email}"/>
<StackPanel>  

视图模型:

    public class myviewmodel
    {

     private string _name;
     public string Name
     {
         get { return _name;}
         set { _name = value; OnPropertyChanged("Name"); }
     } 
      private string _age;
     public string Age
     {
         get { return _age;}
         set { _age = value; OnPropertyChanged("Age"); }
     } 

    private Customer _selectedCustomer;
    public Customer SelectedCustomer
    {
        get { return _selectedCustomer; }
        set { selectedCustomer = value; OnPropertyChanged("SelectedCustomer"); }
    } 


    }

我会将现有客户名称加载到comboxbox。要更新现有的         客户详细信息,如果我在组合框中选择客户名称,则选择客户详细信息         应该绑定在文本框中,以便我可以轻松更新它们。但是文本框文本         属性已用于添加新客户。所以如何添加和更新         客户使用相同的文本框?

2 个答案:

答案 0 :(得分:0)

文本框&#39;绑定未设置为SelectedCustomer。试一试。

<ComboBox ItemsSource="{Binding Customers}" SelectedItem="{Binding SelectedCustomer}" DisplayMemberPath="Name"/>

<Grid Visibility="{Binding ExistingCustomer, Converter={StaticResource VisibilityConverter}}">
    <Textbox Text="{Binding SelectedCustomer.Name, Mode=TwoWay}"/>
    <Textbox Text="{Binding SelectedCustomer.Age, Mode=TwoWay}}"/>
    <Textbox Text="{Binding SelectedCustomer.Phone, Mode=TwoWay}}"/>
    <Textbox Text="{Binding SelectedCustomer.Address, Mode=TwoWay}}"/>
    <Textbox Text="{Binding SelectedCustomer.Email, Mode=TwoWay}}"/>
</Grid>
<Grid Visibility="{Binding ExistingCustomer, Converter={StaticResource VisibilityConverter}}">
    <Textbox Text="{Binding Customer.Name, Mode=TwoWay}"/>
    <Textbox Text="{Binding Customer.Age, Mode=TwoWay}}"/>
    <Textbox Text="{Binding Customer.Phone, Mode=TwoWay}}"/>
    <Textbox Text="{Binding Customer.Address, Mode=TwoWay}}"/>
    <Textbox Text="{Binding Customer.Email, Mode=TwoWay}}"/>
</Grid>

以下是转换器的代码

public class VisibilityConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string culture)
    {
        bool displayControl = (bool)value;

        if (displayControl == true)
        {
            return Visibility.Visible;
        }
        else
        {
            return Visibility.Collapsed;
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, string culture)
    {
        return null;
    }
}

请务必引用转换器所在的命名空间

答案 1 :(得分:0)

使用Interaction Behaviors可以实现这一目标。

首先,Behaviors SDK不是内置的UWP,但必须与NuGet分开下载。

您可以使用以下命令进行安装:

Install-Package Microsoft.Xaml.Behaviors.Uwp.Managed

或者只需使用NuGet包管理器并搜索Microsoft.Xaml.Behaviors.Uwp.Managed

安装后,您只需将XAML using语句添加到页面顶部:

<Page ...
xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
xmlns:core="using:Microsoft.Xaml.Interactions.Core" />

如果您总是要从Combobox SelectedItem绑定TextBox,则无需创建另一个属性SelectedCustomer。除非您打算将SelectedCustomer用于工作背后的其他代码。

以下是如何在没有TextBox财产的情况下实现SelectedCustomer文字。

<ComboBox x:Name="comboBox" ItemsSource="{Binding Customers}" DisplayMemberPath="Name" HorizontalAlignment="Stretch" Margin="5,0">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="SelectionChanged">
            <core:ChangePropertyAction TargetObject="{Binding ElementName=stkData}" PropertyName="DataContext" Value="{Binding SelectedItem, ElementName=comboBox}"  />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</ComboBox>

<StackPanel Orientation="Vertical" Grid.Row="1" Margin="5,20" DataContext="{Binding SelectedItem, ElementName=comboBox}">
    <TextBox Text="{Binding Name, Mode=TwoWay}" PlaceholderText="Name" Name="Name"/>
    <TextBox Text="{Binding Age, Mode=TwoWay}" PlaceholderText="Age" Name="Age"/>
    <TextBox Text="{Binding Phone, Mode=TwoWay}" PlaceholderText="Phone" Name="Phone"/>
    <TextBox Text="{Binding Address, Mode=TwoWay}" PlaceholderText="Address" Name="Address"/>
    <TextBox Text="{Binding Email, Mode=TwoWay}" PlaceholderText="Email" Name="Email"/>
</StackPanel>

如果您注意到,我将comboBox SelectedItem Property中的数据绑定到StackPanel DataContext,然后将Individual Properties直接绑定到TextBox的Text。这将照顾您ComboBox绑定到TextBox。模式应始终为TwoWay,以便在用户修改现有客户详细信息时更新数据。

完成此操作后,如果要使用当前文本框添加新的客户信息,则需要清除选择而不更改当前值。下面是我添加一个具有交互行为的按钮的方法。

并使用Clicked操作清除TextBox文字。在UWP XAML中,您可以使用空字符串作为值,它可以按预期工作。

<Button Content="+" Grid.Column="1" Margin="5,0" Tag="{Binding EmptyClass, Mode=TwoWay}" Name="btnNew">
    <interactivity:Interaction.Behaviors>
        <core:EventTriggerBehavior EventName="Click">
            <core:ChangePropertyAction TargetObject="{Binding ElementName=stkData}" PropertyName="DataContext" Value="{Binding Tag, ElementName=btnNew, Mode=TwoWay}"  />
            <core:ChangePropertyAction TargetObject="{Binding ElementName=comboBox}" PropertyName="SelectedIndex" Value="-1"  />
        </core:EventTriggerBehavior>
    </interactivity:Interaction.Behaviors>
</Button>

另请注意,我将选定的ComboBox索引设为-1,以便无法更新所选数据。

现在保存部分应该非常简单直接。以下是我与TappedEvent

一起使用的按钮
private void saveBtn_Tapped(object sender, TappedRoutedEventArgs e)
{
    model.Customers.Add(model.EmptyClass);
    model.EmptyClass = new MyClass();
}

您可以看到我正在重新复制EmptyClass,以便可以清除旧的绑定数据。

以下是完整XAML

<Page
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:App15"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:Text="using:System.Text"
    x:Class="App15.MainPage"
    xmlns:interactivity="using:Microsoft.Xaml.Interactivity"
    xmlns:core="using:Microsoft.Xaml.Interactions.Core"
    Loaded="Page_Loaded"
    mc:Ignorable="d">

    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
        <Grid Margin="0,100,0,0">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>
            <Grid Grid.Row="0">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*"/>
                    <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <ComboBox x:Name="comboBox" ItemsSource="{Binding Customers}" DisplayMemberPath="Name" HorizontalAlignment="Stretch" Margin="5,0">
                    <interactivity:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="SelectionChanged">
                            <core:ChangePropertyAction TargetObject="{Binding ElementName=stkData}" PropertyName="DataContext" Value="{Binding SelectedItem, ElementName=comboBox}"  />
                        </core:EventTriggerBehavior>
                    </interactivity:Interaction.Behaviors>
                </ComboBox>
                <Button Content="+" Grid.Column="1" Margin="5,0" Tag="{Binding EmptyClass, Mode=TwoWay}" Name="btnNew">
                    <interactivity:Interaction.Behaviors>
                        <core:EventTriggerBehavior EventName="Click">
                            <core:ChangePropertyAction TargetObject="{Binding ElementName=stkData}" PropertyName="DataContext" Value="{Binding Tag, ElementName=btnNew, Mode=TwoWay}"  />
                            <core:ChangePropertyAction TargetObject="{Binding ElementName=comboBox}" PropertyName="SelectedIndex" Value="-1"  />
                        </core:EventTriggerBehavior>
                    </interactivity:Interaction.Behaviors>
                </Button>
            </Grid>
            <StackPanel Orientation="Vertical" Grid.Row="1" Margin="5,20" Name="stkData">
                <TextBox Text="{Binding Name, Mode=TwoWay}" PlaceholderText="Name"/>
                <TextBox Text="{Binding Age, Mode=TwoWay}" PlaceholderText="Age" />
                <TextBox Text="{Binding Phone, Mode=TwoWay}" PlaceholderText="Phone" />
                <TextBox Text="{Binding Address, Mode=TwoWay}" PlaceholderText="Address" />
                <TextBox Text="{Binding Email, Mode=TwoWay}" PlaceholderText="Email" />
            </StackPanel>
            <Button Name="saveBtn" Content="Save" HorizontalAlignment="Stretch" Margin="5" Grid.Column="1" Grid.Row="2" Tapped="saveBtn_Tapped"/>
        </Grid>
    </Grid>
</Page>

以下是完整代码

using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
using Windows.UI.Xaml.Input;

namespace App15
{
    public sealed partial class MainPage : Page
    {
        public MainPage()
        {
            this.InitializeComponent();
        }

        MyViewModel model = new MyViewModel();
        private void Page_Loaded(object sender, RoutedEventArgs e)
        {
            this.DataContext = model;
        }

        private void saveBtn_Tapped(object sender, TappedRoutedEventArgs e)
        {
            model.Customers.Add(model.EmptyClass);
            model.EmptyClass = new MyClass();
        }
    }
}

以下是完整视图模型

public class MyViewModel
{
    public MyViewModel()
    {
        Customers = new ObservableCollection<MyClass>();
        EmptyClass = new MyClass();
        for (int i = 0; i < 10; i++)
        {
            Customers.Add(new MyClass()
            {
                Name = "Item" + (i + 1).ToString(),
                Address = "Address" + (i + 1).ToString(),
                Age = "20" + (i + 1).ToString(),
                Email = "Test" + (i + 1).ToString() + "@test.com",
                Phone = (9876543210 + i).ToString()
            });
        }
    }
    public ObservableCollection<MyClass> Customers { get; set; }
    public MyClass EmptyClass { get; set; }
}

public class MyClass
{
    public string Name { get; set; }
    public string Age { get; set; }
    public string Phone { get; set; }
    public string Address { get; set; }
    public string Email { get; set; }
}

我知道甚至可以在MVVM中使用Save Option但是我没有机会使用DelegateCommand。但是,如果您想自己尝试一下,请查看Video by Jerry Nixon以获取参考