且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

ListView内的TextBox绑定到对象,两种方式的绑定无效

更新时间:2023-02-27 07:39:12


但是当我更改TextBox中的值时,它不会更新回CurrentParameterValue属性的源。

But when I change the values in the TextBox it dosen't update back the source that is the CurrentParameterValue property.



ListView 中的p> Binding 不知道如何更新 object ,因为它是 ItemsSource ,并且只能更新 ICollection ,例如您不能与对象,例如C#中的列表。例如:

Binding in ListView doesn't know how to update the Property of type object because it's ItemsSource and it can update only ICollection such as you can't interact with object like List in C#. for example:

object MyList = new object();
MyList.Add("something"); // Compile error




在我的视图模型中,该对象可以是长列表,双列表等来自外部API。

And in my viewmodel the object which can be a list of long, list of double etc comes from an external API.

那么您需要此解决方案。

You need this solution then.

public class VmServiceMethodsViewDataGridModel : BindableBaseThreadSafe
{
    private List<object> _currentParameterValue; // or ObservableCollection
    public List<object> CurrentParameterValue
    {
        get => _currentParameterValue;
        set => Set(ref _currentParameterValue, value);
    }
}






另外

我不知道您要使用这种语法实现或解决什么

I have no idea what do you want to achieve or solve with this syntax

<ListView ItemsSource="{x:Bind ViewModel.AtlasMethodParameterList,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}">

一切都必须与此

<ListView ItemsSource="{Binding AtlasMethodParameterList}">




  • Mode = TwoWay 是默认模式,您可能未在此处明确包含它。

  • UpdateSourceTrigger = PropertyChanged (默认值为 LostFocus )是在 UI-> VM 方向上需要的,而不是反向的。因此,这里没有用。您可以将其应用于模板中的 TextBox

    • Mode=TwoWay is default Mode, you may not include it here explicitly.
    • UpdateSourceTrigger=PropertyChanged (Default is LostFocus) is needed in UI->VM direction, not in a back way. So, it's useless here. You may apply it to the TextBox in template instead.
    • 编辑

      因为双向绑定需要明确的路径,并且目标必须是包含Setter的属性。

      Because Two-way Binding requires explicit Path and the target must be a Property which contains Setter.

      演示应用的解决方法

<ListView Grid.Row="0" 
          ItemsSource="{Binding Demo.CurrentParameterValue}" 
          HorizontalAlignment="Center" VerticalAlignment="Center">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding Value, UpdateSourceTrigger=PropertyChanged}" Width="100"></TextBox>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>



public partial class MainWindow : Window, INotifyPropertyChanged
{
    private VmServiceMethodsViewDataGridModel _demo;

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
    public VmServiceMethodsViewDataGridModel Demo
    {
        get => _demo;
        set
        {
            _demo = value;
            OnPropertyChanged("Demo");
        }
    }

    public MainWindow()
    {
        InitializeComponent();
        DataContext = this;
        Demo = new VmServiceMethodsViewDataGridModel();
        Demo.CurrentParameterValue.Add(new MyItem { Value = 1 });
        Demo.CurrentParameterValue.Add(new MyItem { Value = 2 });
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        var collection = Demo.CurrentParameterValue;
        MessageBox.Show(string.Format("Values are {0}, {1}", collection[0].Value, collection[1].Value));
    }
}

// here it is
public class MyItem
{
    public object Value { get; set; }
}

public class VmServiceMethodsViewDataGridModel : INotifyPropertyChanged
{
    private List<MyItem> _currentParameterValue;
    public List<MyItem> CurrentParameterValue
    {
        get => _currentParameterValue;
        set
        {
            _currentParameterValue = value;
            OnPropertyChanged("CurrentParameterValue");
        }
    }

    public VmServiceMethodsViewDataGridModel()
    {
        CurrentParameterValue = new List<MyItem>();
    }

    public event PropertyChangedEventHandler PropertyChanged;
    protected void OnPropertyChanged(string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

此外,您还可以为价值与您的需求有关。

Additionally you may implement INPC for the Value regarding to your needs.