【问题标题】:INotifiy interface not updating my XAML InterfaceINotify 接口未更新我的 XAML 接口
【发布时间】:2019-09-10 07:57:35
【问题描述】:

我正在尝试通过构建一个利用 INotifyPropertyChange 的项目来学习 WPF 中的 MVVM,然后我计划添加命令,但我目前无法使用 INotify 更新接口。

我尝试了不同的接口实现,但是当我通过按钮“添加”添加新值时仍然没有得到新值,该按钮只是将固定名称和 ID 添加到我的 SQL 数据库中,请注意该值确实添加到了数据库中

这是 MainWindowView.Xaml

<Window x:Class="simpleMvvM1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        xmlns:viewmodel="clr-namespace:simpleMvvM1.ViewModels"
        Title="MainWindow" Height="880" Width="800">

    <Window.DataContext>
        <viewmodel:MainWindowViewModel/>
    </Window.DataContext>

    <Grid >
        <StackPanel>
            <TextBlock Text="{Binding userCollection}"  Margin="10" >

            </TextBlock>

            <ListBox ItemsSource="{Binding userCollection}" Margin="0 5 0 5" Height="100" Name="ListView">
                <ListBox.ItemTemplate>
                    <DataTemplate>
                        <WrapPanel>
                            <Label Content="{Binding userid  }"></Label>
                            <Label Content="{Binding username}"></Label>

                        </WrapPanel>
                    </DataTemplate>
                </ListBox.ItemTemplate>

            </ListBox>

            <TextBlock Text="Name" Name="NameTextBlock"></TextBlock>
            <TextBox x:Name="NameTextBox"></TextBox>

            <TextBlock Text="ID" Name="IDTextBlock"></TextBlock>
            <TextBox x:Name="IDTextBox"></TextBox>

            <Grid>
                <Grid.ColumnDefinitions></Grid.ColumnDefinitions>
                <DataGrid ItemsSource="{Binding Users_datatable, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" x:Name="UserDataGrid" Height="200"></DataGrid>
            </Grid>


            <Grid Margin="0 10">
                <Grid.ColumnDefinitions></Grid.ColumnDefinitions>
                <ListView ItemsSource="{Binding userCollection}" x:Name="UserListView" Height="200">
                    <ListView.ItemTemplate>
                        <DataTemplate>

                            <StackPanel Orientation="Horizontal">
                            <ListViewItem Content="{Binding userid}"></ListViewItem>
                            <ListViewItem Content="{Binding username}"></ListViewItem>
                            </StackPanel>

                        </DataTemplate>
                    </ListView.ItemTemplate>
                </ListView>
            </Grid>
            <Button
                Name="AddButton" Click="AddButton_Click" 
                >Add</Button>
            <Button>Delete</Button>
            <Button>Update</Button>
            <Button 
                x:Name="ClearButton" 
                Content="Clear" Click="ClearButton_Click"
                    ></Button>
            <Button 
                Content="Close"
                />
        </StackPanel>

    </Grid>
</Window>

这是 MainWindowViewModel.cs

using simpleMvvM1.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Input;

namespace simpleMvvM1.ViewModels
{
    class MainWindowViewModel 
    {



        //Connection string setup. See App for more informatiom
        static string myconnection = ConfigurationManager.ConnectionStrings["simpleMvvM1.Properties.Settings.myTestDbConnectionString"].ConnectionString;
        //DataTable to store the database tables we are using
        public DataTable Users_datatable { get; set; } = new DataTable();

        //collection of the UserTable information
        public ObservableCollection<Models.UserNames> userCollection { get; set; } = new ObservableCollection<UserNames>();



        /// <summary>
        /// Constructor Situation
        /// </summary>
          public MainWindowViewModel()
            {
            getAllUsersNamesTest();
            }



        public ObservableCollection<String> getAllUsersNames()
        {
            SqlConnection con = new SqlConnection(myconnection);
            SqlCommand cmd = new SqlCommand("Select Username from UserTable;");

            con.Open();
            SqlDataAdapter adp = new SqlDataAdapter(cmd);

            ObservableCollection<String> userNames = new ObservableCollection<String>();

            userNames.Add("ImJhonny");

              return userNames;
        }


        /// <summary>
        /// Fills in the DataTable and the Observable Collection for us to use. 
        /// </summary>
        public void getAllUsersNamesTest()
        {
            //Connects to our database
            SqlConnection con = new SqlConnection(myconnection);
            //Saves the command to SqlCommand cmd
            SqlCommand cmd = new SqlCommand("Select*From UserTable;", con);
            //Opens Connection
            con.Open();
            //Stores the table for this session
            SqlDataAdapter adp = new SqlDataAdapter(cmd);
            Users_datatable = new DataTable(); //references the object
            //Filles data Table
            adp.Fill(Users_datatable);
            //Closes connection
            con.Close();


            for (int i = 0; i < Users_datatable.Rows.Count; i++)
            {
                userCollection.Add(new Models.UserNames
                {

                    username = Users_datatable.Rows[i]["UserName"].ToString(),
                    userid = (int)Users_datatable.Rows[i]["UserID"]


                });

            }

        }


        public bool insertIntoDb()
        {
            //Connects to our database
            SqlConnection con = new SqlConnection(myconnection);

            //Create a Boolean variable and set its default value to false
            bool isSuccess = false;
            try
            {


                //Saves the command to SqlCommand cmd
                SqlCommand cmd = new SqlCommand("INSERT INTO UserTable(UserID, UserName) Values (@userid , @username);", con);

                cmd.Parameters.AddWithValue("@username", "Churro");
                cmd.Parameters.AddWithValue("@userid", 13);

                //Opens Connection
                con.Open();

                int rows = cmd.ExecuteNonQuery();

                if (rows > 0)
                {
                    isSuccess = true;

                }
                else
                {
                    isSuccess = false;
                }

            }
            catch (Exception ex)
            {

                MessageBox.Show(ex.Message);
            }
            finally
            {
                con.Close();
            }

            return isSuccess;

        }



        public void ClearTextBoxes()
        {
            MainWindow mw = new MainWindow();
            mw.NameTextBlock.Text = "";
            mw.IDTextBlock.Text = "";


        }

    }

}

最后是 UserNames.cs 模型文件


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace simpleMvvM1.Models
{
    class UserNames : INotifyPropertyChanged

    {
        public event PropertyChangedEventHandler PropertyChanged;
        private void NotifyPropertyChanged(string property)
        {
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(property));
            }
        }



        private int UserID =00;
        public int userid 
        {
            get { return UserID; }
            set
            {
                UserID = value;
                NotifyPropertyChanged("userid");
            }
        }

        private string UserName;


        public string username 
        {
            get { return UserName; }
            set
            {
                UserName = value;
                NotifyPropertyChanged("username");

            }

        }


    }
}

当我按下我的 ADD 按钮时,我预计视图会发生变化,其背后的代码只是从 MainWindowView.Xaml 文件中调用 insertIntoDb() 方法

    MainWindowViewModel mwvm = new MainWindowViewModel();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void AddButton_Click(object sender, RoutedEventArgs e)
    {
        mwvm.insertIntoDb();            
    }

【问题讨论】:

  • "utalizes INotifyPropertyChange" 还不够,目前mwvm.insertIntoDb() 没有发出任何通知。尝试清除 userCollection 并在其末尾调用 getAllUsersNamesTest() 以查看差异,尽管这并不理想。

标签: c# .net wpf xaml


【解决方案1】:

mwvm 与您在视图中绑定的 MainWindowViewModel 实例不同:

<Window.DataContext>
    <viewmodel:MainWindowViewModel/>
</Window.DataContext>

如果您删除上述标记并以编程方式设置 DataContext,则只要您在 insertIntoDb() 方法中实际添加项目,这些项目就会添加到数据绑定集合中:

MainWindowViewModel mwvm = new MainWindowViewModel();

public MainWindow()
{
    InitializeComponent();
    DataContext = mwvm;
}

private void AddButton_Click(object sender, RoutedEventArgs e)
{
    mwvm.insertIntoDb();            
}

顺便说一句,你应该用视图模型中的命令属性替换视图中的Click事件处理程序,并将Button绑定到这个。

【讨论】:

  • 谢谢,我继续并采取了下一步来实现 ICommand 接口,我得到了前端的反应。赞赏
猜你喜欢
  • 1970-01-01
  • 2018-02-22
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 2013-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多