【问题标题】:mvvm:filter wpf listview values from a textboxmvvm:从文本框中过滤 wpf listview 值
【发布时间】:2014-02-12 10:25:59
【问题描述】:

我是 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 中做到这一点?

【问题讨论】:

    标签: c# wpf xaml listview mvvm


    【解决方案1】:

    向您的视图模型添加一个附加属性以显示/隐藏 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 转换器。

    【讨论】:

    • ,on MyViewModel_PropertyChanged if(e.PropertyName == "ProductName") { // update ProductRecords } 你是什么意思 Update ProductRecords 你会澄清
    • 当 ProductRecords 更新(保留 4 条记录)并调用 RaisePropertyChanged("ProductRecords ") 后触发 SelectedProduct 属性 if (SelectedProduct!= null) { ProductName = SelectedProduct.Name;显示产品列表 = 假; } 将重置 ProductName 属性,该属性再次更新 ProductRecords 等等
    • 我已经编辑了我的答案并添加了一个布尔变量来防止属性更改循环。希望这会有所帮助!
    猜你喜欢
    • 1970-01-01
    • 2019-07-16
    • 1970-01-01
    • 2017-08-05
    • 2019-03-15
    • 1970-01-01
    • 1970-01-01
    • 2017-09-02
    • 2012-11-24
    相关资源
    最近更新 更多