简体   繁体   English

如何在WPF MVVM中将变量绑定到列表中?

[英]How to bind a variable within a list in WPF MVVM?

I have an unknown list of variables that I wish to bind to specific controls within a WPF application. 我有一个未知的变量列表,希望将其绑定到WPF应用程序中的特定控件。 Is there a way to bind a variable out of the list with a specific name? 有没有办法用特定名称将列表中的变量绑定?

Here is a code example of what I am trying to do. 这是我正在尝试执行的代码示例。

C# C#

public class Variable {
    public string Name {get;set;}
}

public class VariableViewModel : INotifyPropertyChanged {
    Variable _variable;
    public Variable Variable {
        get {
            return(_variable);
        }
        set {
            _variable = value;
            if(PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs("Variable"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}

public class VariableListViewModel {
    public ObservableCollection<VariableViewModel> VariableList { get; set; }

    public VariableListViewModel() {
        VariableList = new ObservableCollection<VariableViewModel>();
        var variableViewModel = new VariableViewModel { 
            Variable = new Variable { Name = "my_variable_name" } 
        };
        VariableList.Add(variableViewModel);
    }
}

WPF: WPF:

<Window>
    <Window.DataContext>
        <local:VariableListViewModel />
    </Window.DataContext>

    <StackPanel>
        <Label Content="{Binding Path=Name, ElementName=my_variable_name}" />
    </StackPanel>
</Window>

The label is clearly wrong here. 标签在这里显然是错误的。 My question is whether or not what I am trying to achieve is possible? 我的问题是,我试图实现的目标是否可能? I want to be able to display 'my_variable_name'. 我希望能够显示“ my_variable_name”。

-Stuart -斯图尔特

You would normally use a ListView (or other ItemsControl ), and bind its ItemsSource to your collection ( VariableList ). 通常,您将使用ListView (或其他ItemsControl ),并将其ItemsSource绑定到您的集合( VariableList )。

This will cause each item (a VariableViewModel ) to get displayed. 这将导致显示每个项目( VariableViewModel )。 You'd then use a DataTemplate to cause the VariableViewModel to display as a Label bound to Variable.Name . 然后,您将使用DataTemplate使VariableViewModel显示为绑定到Variable.Name的Label。

You could use a ValueConverter and use its ConverterParameter to pass in the name of the variable: 您可以使用ValueConverter并使用其ConverterParameter传入变量的名称:

public object ConvertTo(object value, Type targetType, object parameter, CultureInfo culture)
{
    var variableList = (IEnumerable<Variable>)value;
    var variableName = parameter != null ? parameter.ToString() : string.Empty;
    return variableList.FirstOrDefault(v=>v.Name == variableName);
}

You could then use that converter in XAML as follows:` 然后可以在XAML中使用该转换器,如下所示:

<Label Content="{Binding Path=ListOfVariables, 
                         Converter={StaticResource VariableConverter}, 
                         ConverterParameter='VariableName'}" />

Your question contradicts itself. 您的问题本身矛盾。

On the one hand you say you have an unknown list of variables, on the other hand your View knows which variables it wants to bind to. 一方面,您说自己有一个未知的变量列表,另一方面,您的View知道它要绑定到哪些变量。

So, either you know which variables you want to bind to or you don't know it. 因此,您要么知道要绑定到哪个变量,要么就不知道。

Scenario 1: You know which variables you want to bind to: 方案1:您知道要绑定到哪些变量:

Create a property per Variable in your ViewModel 在ViewModel中为每个变量创建一个属性

Scenario 2: You don't know which variables you want to bind to: 方案2:您不知道要绑定到哪些变量:

Bind your VariableList property to an ItemsControl in the View and provide a DataTemplate that can render a VariableViewModel . 将您的VariableList属性绑定到视图中的ItemsControl上,并提供可以呈现VariableViewModelDataTemplate


BTW: Having a VariableViewModel seems to be superfluous. 顺便说一句:拥有VariableViewModel似乎是多余的。 You could use Variable directly. 您可以直接使用Variable Especially when all VariableViewModel does is returning the Variable inside. 尤其是当所有VariableViewModel都返回内部Variable

Based on Reeds solution and comments, here is my final solution. 根据Reeds的解决方案和评论,这是我的最终解决方案。 I used the same model and view model, so I will only show the View. 我使用了相同的模型和视图模型,因此仅显示视图。

<Window>
    <Window.DataContext>
        <local:VariableListViewModel />
    </Window.DataContext>

    <Window.Resources>
        <DataTemplate x:Key="itemsControlDataTemplate">
            <Label x:Name="label" Content="{Binding Variable.Name}">
                <Label.Style>
                    <Style TargetType="{x:Type Label}">
                        <Setter Property="Visibility" Value="Collapsed" />
                        <Style.Triggers>
                            <Trigger Property="Content" Value="my_variable_name">
                                <Setter Property="Visibility" Value="Visible" />
                            </Trigger>
                        </Style.Triggers>
                    </Style>
                </Label.Style>
            </Label>
        </DataTemplate>
    </Window.Resources>

    <StackPanel>
        <ItemsControl ItemTemplate="{StaticResource itemsControlDataTemplate}" ItemsSource="{Binding Path=VariableList}" />
    </StackPanel>
</Window>

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

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