繁体   English   中英

mvvm:从文本框中过滤WPF ListView值

[英]mvvm:filter wpf listview values from a textbox

我是MVVM的新手,我有一个要求。我有一个文本框和一个列表视图。当用户在文本框中输入文本时,列表视图通过过滤文本填充了数据。 用户可以从列表视图中选择一个项目,然后文本框将获得SelectedValue,而列表视图将变为不可见(在选择了一个项目之后)。我可以使用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中做到这一点?

在视图模型中添加一个附加属性以显示/隐藏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 ,您需要一个布尔到可见性转换器。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM