繁体   English   中英

WPF MVVM绑定到DataTemplate的集合

[英]WPF MVVM Binding collection to DataTemplate

我有一个ViewModel,它具有一个ObservableCollection<MyData> MainCollectionMyData SelectedData ,其中包含从MainCollection当前选择的项目。 MyData包含多个属性,还包含ObservableCollection<MyValuePair> MyPairs MyValuePair由2个属性DescriptionValue组成,就像KeyValuePair一样(无法使用字典,因为我想具有TwoWay绑定)。

我想根据我的DataTemplate动态地为每个MyValuePair创建控件(我正在尝试这样做: 在WPF MVVM中动态添加控件 ):

        //do not want to create another viewModel
        <DataTemplate DataType="{x:Type vm:MyValuePairViewModel }">
        <Grid>
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto"/>
            </Grid.RowDefinitions>

            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>

            //problem can only select one MyValuePair at a time
            <TextBlock Text="{Binding MyValuePair.Description, Mode=TwoWay}"/>
            <TextBox Template="{StaticResource TextBoxBaseControlTemplate}" Grid.Row="0" Grid.Column="1" Text="{Binding MyValuePair.Value, Mode=TwoWay}"/>
        </Grid>
    </DataTemplate>

迈德特:

public class MyData
{
    //Properties
    ObservableCollection<MyValuePair> MyPairs { get; set; }
}

MainViewModel:

public class MainViewModel : ViewModelBase
{
    ObservableCollection<MyData> MainCollection { get; set; }

    MyData selectedData
    public MyData SelectedData
    {
        get { return selectedData; }
        set
        {
            Set(() => SelectedData, ref selectedData, value);
        }
    }
}

MyValuePair:

public class MyValuePair
{
    private string description;
    public string Description
    {
        get { return description; }
        set { description = value; }
    }

    private string _value;
    public string Value
    {
        get { return _value; }
        set { _value = value; }
    }

但问题是我不想为我创建另一个视图模型(MyValuePairViewModel) MyValuePair ,因为那时我已经把它与我的MainViewModel每次的SelectedData改变或者如果MyPair(类型MyValuePair)的同步变化我必须把它同步回MainViewModel,感觉不对。

那么,是否有一种简单的方法可以将我的DataTemplate直接绑定到SelectedData中ObservableCollection<MyValuePair>属性内的每个元素,以便为每个MyPair创建DataTemplate?


编辑目前,我正在使用另一个ViewModel:

public class MyValuePairViewModel : ViewModelBase
{
    private MyValuePair myValuePair;
    public MyValuePair MyValuePair
    {
        get { return myPair; }
        set
        {
            Set(() => MyValuePair, ref myValuePair, value);
        }
    }

    public MyValuePairViewModel(MyValuePair myValuePair)
    {
        MyValuePair = myValuePair;
    }
}

并将其添加到我的MainViewModel中,如下所示:
public ObservableCollection<MyValuePairViewModel> MyPairs { get; set; } public ObservableCollection<MyValuePairViewModel> MyPairs { get; set; }
因此,对于MyPairs中的每个元素,我都创建了上面的DataTemplate

每当ListView的选择更改时,我都会执行以下操作:

public void RefreshKeyValuePairs()
    {
        if (MyPairs != null)
        {
            MyPairs.Clear();
        }

        if (SelectedData != null)
        {
            foreach (MyValuePair item in SelectedData.MyPairs)
            {
                MyValuePairViewModel vm = new MyValuePairViewModel(item);
                MyPairs.Add(vm);
            }
        }
    }

但是,在这种情况下,每当我在创建的TextBox中键入内容时,它都不会在MainViewModel的SelectedData中仅在MyValuePairViewModel内更新,并且我必须在MyValuePairViewModel Set方法内手动将其同步到MainViewModel的SelectedData(但这还要求我拥有实例在MyValuePairViewModel内部的MainViewModel)。

换句话说,我想直接绑定到创建的元素SelectedData.MyPairs[0].Description绑定到第一个创建的TextBlock, SelectedData.MyPairs[1].Description绑定到第二个创建的TextBlock,依此类推,以便它自动在两个方向上更新。 如果SelectedData.MyPairs不是集合,而是普通属性,则可以直接绑定到它。

您可以将UI元素直接绑定到MyValuePair对象。 您不需要特定的ViewModel类MyValuePairViewModel。

您唯一会错过的是MyValuePair上INotifyPropertyChanged的实现。 UI将正常初始化,但是初始化后对Description和Value属性的编程更新将不会出现在UI中。 如果您不进行任何程序更新,这将不是问题。

如果要更改Description和Value属性,最简单的方法是直接在MyValuePair上实现INotifyPropertyChanged。 这仅需要几行代码,并且比使用单独的类MyValuePairViewModel复制功能要容易。

暂无
暂无

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

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