WPF: вложенные свойства зависимости - PullRequest
0 голосов
/ 06 мая 2011

У меня есть ObservableCollection «Layouts» и «SelectedLocation» DependencyProperty для окна.SelectedLocation имеет свойство «Layout», которое представляет собой объект, содержащий поля, такие как «Name» и т. Д. Я пытаюсь связать комбинированный список с SelectedLayout, но он не работает.Следующее не работает, я попытался связать с SelectedItem вместо этого безрезультатно.Я полагаю, что это может быть связано с тем фактом, что я связываюсь с подпроцессом свойства SelectedLocation DependencyProperty (хотя это действительно реализует INotifyPropertyChanged.

<ComboBox Grid.Row="2" Grid.Column="0" x:Name="cboLayout" ItemsSource="{Binding Layouts,ElementName=root}" SelectedValue="{Binding SelectedLocation.Layout.LayoutID,ElementName=root}" DisplayMemberPath="{Binding Name}" SelectedValuePath="LayoutID" />

Однако, следующие работы (также связанные с "Выбранное местоположение "DP:

<TextBox Grid.Row="4" Grid.Column="1" x:Name="txtName" Text="{Binding SelectedLocation.Name,ElementName=root,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" />

1 Ответ

1 голос
/ 06 мая 2011

Какое свойство типа Layouts имеет? Я полагаю, что-то вроде этого: IEnumerable<Layout>. Но вы привязываете выбранное значение к Layout.LayoutID. Итак, у вас возникла ситуация, когда в поле со списком Layout объектов вы пытаетесь выбрать его по идентификатору Int. Конечно, механизм связывания не может найти там Int.

Я не имею представления о деталях вашего кода, поэтому могу предложить одну вещь: попытаться уменьшить ваше выражение привязки: SelectedItem="{Binding SelectedLocation.Layout,ElementName=root}.

Если ничего не получится, предоставьте больше кода, чтобы помочь мне понять, что происходит.

==== ==== UPDATE

Как я уже сказал, вы, очевидно, делаете что-то не так. Но я не паранормалист и не могу угадать причину вашего отказа ( без вашего кода ). Если вы не хотите делиться своим кодом, я решил привести простой пример, чтобы продемонстрировать, что все работает. Посмотрите на код, показанный ниже, и скажите мне, что отличается в вашем приложении.

Class Layout, который предоставляет свойство LayoutId:

public class Layout
{
    public Layout(string id)
    {
        this.LayoutId = id;
    }

    public string LayoutId
    {
        get;
        private set;
    }

    public override string ToString()
    {
        return string.Format("layout #{0}", this.LayoutId);
    }
}

Класс SelectionLocation, который имеет вложенное свойство Layout:

public class SelectedLocation : INotifyPropertyChanged
{
    private Layout _layout;

    public Layout Layout
    {
        get
        {
            return this._layout;
        }
        set
        {
            this._layout = value;
            this.OnPropertyChanged("Layout");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string name)
    {
        var safeEvent = this.PropertyChanged;
        if (safeEvent != null)
        {
            safeEvent(this, new PropertyChangedEventArgs(name));
        }
    }
}

И класс Window со свойствами зависимости (фактически, в моем примере StartupView - это UserControl, но это не имеет значения):

public partial class StartupView : UserControl
{
    public StartupView()
    {
        InitializeComponent();

        this.Layouts = new Layout[] { new Layout("AAA"), new Layout("BBB"), new Layout("CCC") };
        this.SelectedLocation = new SelectedLocation();
        this.SelectedLocation.Layout = this.Layouts.ElementAt(1);
    }

    public IEnumerable<Layout> Layouts
    {
        get
        {
            return (IEnumerable<Layout>)this.GetValue(StartupView.LayoutsProperty);
        }
        set
        {
            this.SetValue(StartupView.LayoutsProperty, value);
        }
    }

    public static readonly DependencyProperty LayoutsProperty =
        DependencyProperty.Register("Layouts",
            typeof(IEnumerable<Layout>),
            typeof(StartupView),
            new FrameworkPropertyMetadata(null));

    public SelectedLocation SelectedLocation
    {
        get
        {
            return (SelectedLocation)this.GetValue(StartupView.SelectedLocationProperty);
        }
        set
        {
            this.SetValue(StartupView.SelectedLocationProperty, value);
        }
    }

    public static readonly DependencyProperty SelectedLocationProperty =
        DependencyProperty.Register("SelectedLocation",
            typeof(SelectedLocation),
            typeof(StartupView),
            new FrameworkPropertyMetadata(null));
}

XAML StartupView:

<UserControl x:Class="Test.StartupView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:self="clr-namespace:HandyCopy"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             Name="Root">
    <WrapPanel>
        <ComboBox ItemsSource="{Binding Path=Layouts,ElementName=Root}"
                  SelectedItem="{Binding Path=SelectedLocation.Layout, ElementName=Root}"/>
    </WrapPanel>
</UserControl>
...