mvvm:从文本框中过滤wpf listview值

时间:2014-02-12 10:25:59

标签: c# wpf xaml listview mvvm

我是MVVM的新手。我有一个要求。我有一个文本框和一个列表视图。当用户在文本框中输入文本时,listview通过过滤文本来填充数据。并且用户可以从列表视图中选择一个项目然后文本框获取Selectedvalue并且listview变得不可见(在选择项目之后)。我可以在wpf普通代码中执行此操作,但我不知道如何在MVVM模式中执行此操作。这是我在普通wpf中的视图:

<TextBox  Name="txtbxProductName"
          TextChanged="txtbxProductName_TextChanged"
          KeyUp="txtbxProductName_KeyUp"
          />

<ListView Name="lstvwProduct"
          Visibility="Collapsed"
          MouseLeftButtonUp="lstvwProduct_MouseLeftButtonUp"
          KeyDown="lstvwProduct_KeyDown">
    <ListView.View>
      <GridView>
        <GridViewColumn DisplayMemberBinding="{Binding Path=Product_Name}"
                        Header="Product Name"
                        Width="240" />
         <GridViewColumn DisplayMemberBinding="{Binding Path=Product_Code}"
                         Header="Product Code"
                         Width="80" />
        </GridView>
       </ListView.View>
     </ListView>

这是我的代码背后的事件:

private void txtbxProductName_TextChanged(object sender, TextChangedEventArgs e)
{
    if (txtbxProductName.Text.Trim() != "")
    {
        string Query = "select PM.Record_Id ,PM.Product_Code,PM.Product_Name,PTM.Product_Type from dbo.Tbl_Product_Master PM  where PM.Is_Del='false' and PM.Product_Name like '%" + txtbxProductName.Text + "%' order by PM.Product_Name ";
        DataSet ds = new DataSet();
        ds = ObjCommon.GetObject.ExecuteQuery_Select(Connection.ConnectionString, Query);
        if (ds.Tables[0].Rows.Count != 0)
        {
            lstvwProduct.Visibility = Visibility.Visible;
            lstvwProduct.ItemsSource = ds.Tables[0].DefaultView;
        }
        else
        {
            lstvwProduct.Visibility = Visibility.Collapsed;
        }
    }
    else
    {
        lstvwProduct.Visibility = Visibility.Collapsed;
    }
}

private void txtbxProductName_KeyUp(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Escape)
    {
        txtbxProductName.Text = "";
        lstvwProduct.Visibility = Visibility.Collapsed;
    }
    else if (e.Key == Key.Down)
    {
        lstvwProduct.Focus();
        lstvwProduct.SelectedIndex = 0;
    }
}

private void lstvwProduct_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (lstvwProduct.SelectedIndex != -1)
    {
        DataRowView drv = (DataRowView)lstvwProduct.SelectedItem;
        txtbxProductName.Text = drv.Row["Product_Name"].ToString();
        lstvwProduct.Visibility = Visibility.Collapsed;
    }
}

private void lstvwProduct_KeyDown(object sender, KeyEventArgs e)
{
    if (e.Key == Key.Enter)
    {
        if (lstvwProduct.SelectedItem != null)
        {
            DataRowView drv = (DataRowView)lstvwProduct.SelectedItem;
            txtbxProductName.Text = drv.Row["Product_Name"].ToString();
            lstvwProduct.Visibility = Visibility.Collapsed;
        }
    }
    else if (e.Key == Key.Escape)
    {
        lstvwProduct.Visibility = Visibility.Collapsed;
        txtbxProductName.Focus();
    }
}

如何在MVVM中完成此操作这是我的视图:

<TextBox  Name="txtbxProductName"
          Width="119"
          Text="{Binding Path=ProductName,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}"
          />

 <ListView ItemsSource="{Binding Path=ProductRecords}"
           SelectedItem="{Binding Path=SelectedProduct,Mode=TwoWay}"
           IsSynchronizedWithCurrentItem="True"
           Name="lstvwProduct"
            >
      <ListView.View>
        <GridView>
          <GridViewColumn DisplayMemberBinding="{Binding Path=ProductName}"
                          Header="Product Name"
                          Width="100" />
          <GridViewColumn DisplayMemberBinding="{Binding Path=ProductCode}"
                          Header="Product Code"
                           Width="100" />
         </GridView>
      </ListView.View>
 </ListView>

这是我的ViewModel属性:

private string _productName;
public string ProductName
{
    get { return _productName; }
    set
    {
        _productName = value;
        RaisePropertyChanged("ProductName");
    }
}
private List<Tbl_Product_Master> _ProductRecords;
public List<Tbl_Product_Master> ProductRecords
{
    get { return _ProductRecords; }
    set
    {
        _ProductRecords = value;
        RaisePropertyChanged("ProductRecords");
    }
}
 private Tbl_Product_Master _selectedProduct;
 public Tbl_Product_Master SelectedProduct
{
    get { return _selectedProduct; }
    set
    {
        _selectedProduct = value;
        RaisePropertyChanged("SelectedProduct");
    }
}

如何在MVVM中执行此操作?

1 个答案:

答案 0 :(得分:0)

向viewmodel添加其他属性以显示/隐藏ListView:

private bool showProductList;
public bool ShowProductList
{
   get { return showProductList; }
   set 
   { 
       showProductList = value;
       RaisePropertyChanged("ShowProductList");
   }
}

在Viewmodel中连接PropertyChanged处理程序并根据需要设置属性:

public MyViewModel()
{
   PropertyChanged += MyViewModel_PropertyChanged;
}

private bool handleSelectedProductChanges = true;

void MyViewModel_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
   if(e.PropertyName == "ProductName")
   {
      handleSelectedProductChanges = false;

      // update ProductRecords

      handleSelectedProductChanges = true;
   }
   else if(e.PropertyName == "SelectedProduct")
   {
      if (handleSelectedProductChanges && SelectedProduct != null)
      {
          ProductName = SelectedProduct.Name;
          ShowProductList = false;
      }
    }
}

要绑定ListView的Visibility,您需要一个bool-to-visibility转换器。