2

我希望能够通过使用枚举从 XAML 中的 ObservableCollection 访问项目。

我可以绑定到 ObservableCollection 并通过以下方式指定 XAML 中的哪个项目:

<Window x:Class="ArrayPropertyBinding.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:ArrayPropertyBinding"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MyViewModel />
    </Window.DataContext>
    <StackPanel>
        <CheckBox Content="First" IsChecked="{Binding FilterBy[0],Mode=TwoWay}"/>
        <CheckBox Content="Second" IsChecked="{Binding FilterBy[1],Mode=TwoWay}"/>
        <CheckBox Content="Thrid" IsChecked="{Binding FilterBy[2],Mode=TwoWay}"/>
        <CheckBox Content="Fourth" IsChecked="{Binding FilterBy[3],Mode=TwoWay}"/>
        <Button Content="Print" Click="Button_Click_1"/>
        <Button Content="SetFourthTrue" Click="Button_Click_SetFourthTrue"/>
    </StackPanel>
</Window>

虽然视图模型看起来像这样

public class MyViewModel
{
    public enum Filters
    {
        First = 0,
        Second,
        Thrid,
        Fourth
    }

    private ObservableCollection<bool> _filterBy = new ObservableCollection<bool>() { false, false, false, false };
    public ObservableCollection<bool> FilterBy
    {
        get { return _filterBy; }
    }

    public void PrintFilters()
    {
        System.Diagnostics.Debug.Write("<<<<");
        foreach (bool b in _filterBy)
        {
            System.Diagnostics.Debug.Write(b);
            System.Diagnostics.Debug.Write(" ");
        }
        System.Diagnostics.Debug.WriteLine(">>>>");
    }

    public void SetFourthTrue()
    {
        FilterBy[(int)Filters.Fourth] = true;
    }
}

我希望能够这样编写 XAML:

<CheckBox Content="First" IsChecked="{Binding FilterBy[Filters.First],Mode=TwoWay}"/>

任何指针或想法将不胜感激。

4

2 回答 2

3

可能归结为自定义绑定路径构造,因为尝试直接输入enum值似乎是不可能的。

那么语法是:

{Binding Path={me:PathConstructor FilterBy[(0)], {x:Static myns:Filters.First}}}

(建议将枚举移出类,否则myns:MyViewModel+Filters.First如果我没记错的话)

于 2013-07-22T18:24:15.057 回答
1

所以,这就是我在HB回答后得到的。它对我很有效。

<StackPanel>
    <CheckBox Content="First" IsChecked="{Binding Path={local:PathConstructor FilterBy, {x:Static local:Filters.First}}}"/>
    <CheckBox Content="Second" IsChecked="{Binding Path={local:PathConstructor FilterBy, {x:Static local:Filters.Second}}}"/>
    <CheckBox Content="Thrid" IsChecked="{Binding FilterBy[2],Mode=TwoWay}"/>
    <CheckBox Content="Fourth" IsChecked="{Binding FilterBy[3],Mode=TwoWay}"/>
    <Button Content="Print" Click="Button_Click_1"/>
    <Button Content="SetFourthTrue" Click="Button_Click_SetFourthTrue"/>
</StackPanel>

在后面的代码中

public static class StringEnumConversion
{
    public static int ConvertToEnum<T>(object value)
    {
        Contract.Requires(typeof(T).IsEnum);
        Contract.Requires(value != null);
        Contract.Requires(Enum.IsDefined(typeof(T), value.ToString()));
        return (int)Enum.Parse(typeof(T), value.ToString());
    }
}

[ContentProperty("Parameters")]
public class PathConstructor : MarkupExtension
{
    public string Path { get; set; }
    public IList Parameters { get; set; }

    public PathConstructor()
    {
        Parameters = new List<object>();
    }

    public PathConstructor(string b, object p0)
    {
        Path = b;
        Parameters = new[] { p0 };
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return new PropertyPath(String.Format("{0}[{1}]",Path,StringEnumConversion.ConvertToEnum<Filters>(Parameters[0])));
    }
}
于 2013-07-24T00:51:38.770 回答