OnPropertyChange调用但未对UI产生任何影响

时间:2013-11-07 16:30:39

标签: wpf mvvm

当我设置我的ViewModel的属性时(我指的是实现INotifyPropertyChanged并且是视图的DataContext的类),OnPropertyChange被调用,但它只是跳过“handler(this,new PropertyChangedEventArgs(name)) “因为PropertyChanged为null,因此UI没有更新。下面是我的代码:

XAML:

<Window x:Class="Magic_Vehicle_Portal_MVVM.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Magic_Vehicle_Portal_MVVM"
    xmlns:vehicle="clr-namespace:Magic_Vehicle_Portal_MVVM.Vehicle"
    Title="MainWindow" Height="600" Width="800"
    >
<Grid >
    <Grid.DataContext>
        <vehicle:VehicleBase />
    </Grid.DataContext>
    <Grid.Resources>
        <Style x:Key="textBlockStyle"
               TargetType="TextBlock">
            <Setter Property="VerticalAlignment"
                    Value="Center" />
        </Style>
        <Style x:Key="textBoxStyle"
               TargetType="TextBox">
            <Setter Property="VerticalAlignment"
                    Value="Center" />
            <Setter Property="HorizontalAlignment"
                    Value="Left" />
            <Setter Property="Height"
                    Value="22" />
            <Setter Property="Width"
                    Value="200" />
        </Style>
        <Style x:Key="comboBoxStyle"
               TargetType="ComboBox">
            <Setter Property="VerticalAlignment"
                    Value="Center" />
            <Setter Property="HorizontalAlignment"
                    Value="Left" />

            <Setter Property="Height"
                    Value="22" />
            <Setter Property="Width"
                    Value="200" />
        </Style>
        <Style x:Key="datePickerStyle"
               TargetType="DatePicker">
            <Setter Property="VerticalAlignment"
                    Value="Center" />
            <Setter Property="HorizontalAlignment"
                    Value="Left" />
            <!--<Setter Property=""
                        Value="" />-->
            <Setter Property="Height"
                    Value="24" />
            <Setter Property="Width"
                    Value="200" />
        </Style>
     </Grid.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30" />
            <RowDefinition Height="*" />
        </Grid.RowDefinitions>
        <Grid Grid.Row="0">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="2*" />
                <ColumnDefinition Width="2*" />
                <ColumnDefinition Width="160" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="0"
                       Style="{StaticResource ResourceKey=textBlockStyle}" 
                       Text="Product Type"
                       Margin="10,2,0,0"/>
            <ComboBox Grid.Column="1"
                       Name="prodcutTypeTextblock"
                       Style="{StaticResource ResourceKey=comboBoxStyle}"
                       Margin="10,2,0,0"
                       ItemsSource="{Binding Path=Product_Type_List}"
                       Text="{Binding Path=Product_Type}" />
            <TextBox Grid.Column="2"
                     Name="searchKeyWordBox"
                     Style="{StaticResource ResourceKey=textBoxStyle}" 
                     HorizontalAlignment="Right"/>
            <Button Grid.Column="3"
                    Content="Search"
                    Width="120"
                    Height="22"
                    Margin="10,2,0,2"
                    HorizontalAlignment="Left"
                    Click="Search_Click"
                    IsDefault="True" />
        </Grid>
        <Grid Grid.Row="1">
            <Grid.RowDefinitions>
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
                <RowDefinition Height="40" />
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="20" />
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="120" />
                <ColumnDefinition Width="*" />
                <ColumnDefinition Width="20" />
            </Grid.ColumnDefinitions>
            <TextBlock Grid.Column="1"
                       Grid.Row="0"
                       Text="Name"
                       Style="{StaticResource ResourceKey=textBlockStyle}"
                       FontWeight="Bold" />
            <TextBox Grid.Column="2"
                     Grid.ColumnSpan="3"
                     Grid.Row="0"
                     Width="565"
                     Style="{StaticResource ResourceKey=textBoxStyle}"
                     Text="{Binding Path=Vehicle_Name}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="1"
                       Text="Onshore"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <CheckBox Grid.Column="2"
                      Grid.Row="1"
                      Content=""
                      VerticalAlignment="Center"
                      HorizontalAlignment="Left" />
            <TextBlock Grid.Column="1"
                       Grid.Row="2"
                       Text="Currency"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <ComboBox Grid.Column="2"
                      Grid.Row="2"
                      Style="{StaticResource ResourceKey=comboBoxStyle}"
                      ItemsSource="{Binding Path=Currency_List}"
                      SelectedItem="{Binding Path=Currency}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="3"
                       Text="CUSIP"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <TextBox Grid.Column="2"
                     Grid.Row="3"
                     Style="{StaticResource ResourceKey=textBoxStyle}"
                     Text="{Binding Path=CUSIP}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="4"
                       Text="ISIN"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <TextBox Grid.Column="2"
                     Grid.Row="4"
                     Style="{StaticResource ResourceKey=textBoxStyle}"
                     Text="{Binding Path=ISIN}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="5"
                       Text="Ticker"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <TextBox Grid.Column="2"
                     Grid.Row="5"
                     Style="{StaticResource ResourceKey=textBoxStyle}"
                     Text="{Binding Path=Ticker}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="6"
                       Text="Valoren"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <TextBox Grid.Column="2"
                     Grid.Row="6"
                     Style="{StaticResource ResourceKey=textBoxStyle}"
                     Text="{Binding Path=Valoren}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="7"
                       Text="SAC Class"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <ComboBox Grid.Column="2"
                      Grid.Row="7"
                      Style="{StaticResource ResourceKey=comboBoxStyle}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="8"
                       Text="PC Class"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <ComboBox Grid.Column="2"
                      Grid.Row="8"
                      Style="{StaticResource ResourceKey=comboBoxStyle}"
                      ItemsSource="{Binding Path=PC_Class_List}"
                      SelectedItem="{Binding Path=PC_Class}" />
            <TextBlock Grid.Column="1"
                       Grid.Row="9"
                       Text="Implementation Type"
                       Style="{StaticResource ResourceKey=textBlockStyle}" />
            <ComboBox Grid.Column="2"
                      Grid.Row="9"
                      Style="{StaticResource ResourceKey=comboBoxStyle}"
                      ItemsSource="{Binding Path=Implementation_Type_List}"
                      SelectedItem="{Binding Path=Implementation_Type}" />
            <ContentControl Grid.Row="1"
        </Grid>

    </Grid>

</Grid>

主窗口:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private VehicleBase _selected_vehicle = new VehicleBase();
    public VehicleBase Selected_Vehicle
    {
        get
        {
            return _selected_vehicle;
        }
        set
        {
            _selected_vehicle = value;
        }
    }

    private void Search_Click(object sender, RoutedEventArgs e)
    {
        string keyword = searchKeyWordBox.Text;
        //int vehicle_id;
        string query;
        DataView dv;

        query = string.Format("select * from dbo.vehicle_attributes where vehicle_id = '{0}'",keyword);

        dv = Utility.DAL.ExecuteQuery(query);
        Selected_Vehicle.Vehicle_Name = dv[0]["vehicle_name"].ToString();
        Selected_Vehicle.OnPropertyChanged("Vehicle_Name");
        //vehicleSearchResults.ItemsSource = dv;
        //statusTextBlock.Text = string.Format("{0} Vehicle(s) Found", dv.Count);
    }
}

视图模型:

public class VehicleBase: INotifyPropertyChanged 
    {
        public VehicleBase()
        {
            //Product_Type = product_type;
            SetLists();
            Product_Type = "Structure";
        }


        private void SetLists()
        {
            SetList_Product_Type();
            SetList_Currency();
            SetList_PC_Class();
        }



        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }


        //ProductType
        private List<string> _product_Type_List = new List<string>();
        public List<string> Product_Type_List
        {
            get
            {
                return _product_Type_List;
            }
            set
            {
                _product_Type_List = value;
                OnPropertyChanged("Product_Type_List");
            }
        }
        private void SetList_Product_Type()
        {
            string query = "SELECT * FROM dbo.product_types WHERE is_enabled = 1";
            DataView dv = Utility.DAL.ExecuteQuery(query);
            List<string> l = new List<string>();
            for (int i = 0; i < dv.Count; i++)
            {
                l.Add(dv[i]["product_type_name"].ToString());
            }
            Product_Type_List = l;

        }

        private string _product_type;
        public string Product_Type
        {
            get
            {
                return _product_type;
            }
            set
            {
                _product_type = value;
                OnPropertyChanged("Product_Type");
            }
        }

        // Vehicle Name
        private string _vehicle_Name;
        public string Vehicle_Name
        {
            get
            {
                return _vehicle_Name;
            }
            set
            {
                _vehicle_Name = value;
                OnPropertyChanged("Vehicle_Name");

            }
        }
    }

视图模型:

    <!-- language: c# -->

    public class VehicleBase: INotifyPropertyChanged 
    {
        public VehicleBase()
        {
            //Product_Type = product_type;
            SetLists();
            Product_Type = "Structure";
        }


        private void SetLists()
        {
            SetList_Product_Type();
            SetList_Currency();
            SetList_PC_Class();
        }



        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged(string name)
        {
            PropertyChangedEventHandler handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(name));
            }
        }


        //ProductType
        private List<string> _product_Type_List = new List<string>();
        public List<string> Product_Type_List
        {
            get
            {
                return _product_Type_List;
            }
            set
            {
                _product_Type_List = value;
                OnPropertyChanged("Product_Type_List");
            }
        }
        private void SetList_Product_Type()
        {
            string query = "SELECT * FROM dbo.product_types WHERE is_enabled = 1";
            DataView dv = Utility.DAL.ExecuteQuery(query);
            List<string> l = new List<string>();
            for (int i = 0; i < dv.Count; i++)
            {
                l.Add(dv[i]["product_type_name"].ToString());
            }
            Product_Type_List = l;

        }

        private string _product_type;
        public string Product_Type
        {
            get
            {
                return _product_type;
            }
            set
            {
                _product_type = value;
                OnPropertyChanged("Product_Type");
            }
        }

        // Vehicle Name
        private string _vehicle_Name;
        public string Vehicle_Name
        {
            get
            {
                return _vehicle_Name;
            }
            set
            {
                _vehicle_Name = value;
                OnPropertyChanged("Vehicle_Name");

            }
        }
     }

2 个答案:

答案 0 :(得分:1)

在MainWindow.Xaml中使用的DataContext Instance和Instance是不同的,PropertyChanged将仅挂钩到绑定到UI的实例。我认为你是这样做的,因为你遇到Button Click问题并在ViewModel中遇到问题,如果是这样的话,在ViewModel中实现ICommand来处理按钮点击事件,在这种情况下你所有的代码都在一个地方,并且您可以轻松地操纵数据。另外,你必须制作你的ViewModel SingleTon类,你必须在每个地方使用相同的实例。

再观察一次。使用observablecollection而不是List,因为List没有实现INotifyPropertyChanged,因此当您添加新项时,它不会反映在UI中,因为observablecollection实现了INotifyPropertyChanged

请参阅以下链接

http://www.c-sharpcorner.com/UploadFile/1a81c5/a-simple-wpf-application-implementing-mvvm/

http://www.c-sharpcorner.com/UploadFile/e06010/wpf-icommand-in-mvvm/

答案 1 :(得分:0)

您可以在MainWindow.Xaml.cs中更改此类内容,如下所示

private VehicleBase _selected_vehicle = new VehicleBase();

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

并保留剩余的代码,不需要进行任何更改。从Xmal文件中重新创建DataContext。这将解决您的问题,无需将Viewmodel设为SingleTon。

或者如果你只想将dataContext设置为网格,那么你可以给网格命名为grid1并将dataContext设置为如下,而不是设置为整个窗口

public MainWindow()
{
    InitializeComponent();
    grid1.DataContext=_selected_vehicle;
}