Задержка привязки экспандера до его расширения - PullRequest
3 голосов
/ 03 апреля 2012

У меня есть окно с привязкой к ViewModel. ViewModel имеет много свойств, некоторые из которых являются дорогостоящими для оценки и не всегда нужны пользователю.

То, что я хотел бы сделать - это привязать данные свойства к элементам управления, содержащимся в разных нерасширенных расширителях. Когда расширитель расширяется пользователем, я бы хотел, чтобы элементы управления связывались и свойства оценивались. Если пользователь не расширяет расширитель, свойства не должны оцениваться, а стоимость не понесена.

Конечно, я мог бы сделать это, используя события из экспандера, но я пытаюсь найти хороший способ сделать это в MVVM. Есть предложения?

Ответы [ 3 ]

2 голосов
/ 03 апреля 2012

@ Предложение Алена выглядит интересно.

Кроме того, поскольку ваши свойства оценивать дорого, вы должны также рассмотреть асинхронные и приоритетные привязки.

Асинхронный пример:

<TextBox Text={Binding Path=Description, IsAsync="True"}/>

Установка IsAsync = True не позволит оценке привязки блокировать поток пользовательского интерфейса.

Вы также можете использовать приоритетное связывание, которое является формой множественного связывания:

<Grid>
    <Grid.DataContext>
        <Samples:PriorityBindingViewModel/>
    </Grid.DataContext>
    <TextBox>
        <TextBox.Text>
            <PriorityBinding>
                <Binding Path="ExpensiveProperty" Mode="OneWay" IsAsync="True"/>
                <Binding Path="LessExpensiveProperty" Mode="OneWay" IsAsync="True"/>
                <Binding Path="LeastExpensiveProperty" Mode="OneWay" IsAsync="True"/>
            </PriorityBinding>
        </TextBox.Text>
    </TextBox>
</Grid>

Привязки оцениваются с приоритетом сверху вниз. Это позволяет поместить, например, сообщение «загрузка ...» в привязку с самым низким приоритетом (LeastExорогоProperty) во время оценки высокоприоритетных, но более медленных привязок.

public class PriorityBindingViewModel
{
    private string _expensiveProperty;

    private string _lessExpensiveProperty;

    public PriorityBindingViewModel()
    {
        ExpensiveProperty = "Loaded";
        LessExpensiveProperty = "Still loading";
        LeastExpensiveProperty = "Loading";
    }

    public string ExpensiveProperty
    {
        get
        {
            // Thread.Sleep is in place of an 'expensive' operation.
            // Just in case anyone doesn't realize.
            Thread.Sleep(8000);  
            return _expensiveProperty;
        }
        private set { _expensiveProperty = value; }
    }

    public string LessExpensiveProperty
    {
        get
        {
            // Same here.
            Thread.Sleep(3000);
            return _lessExpensiveProperty;
        }
        private set { _lessExpensiveProperty = value; }
    }

    public string LeastExpensiveProperty { get; private set; }
}
1 голос
/ 03 апреля 2012
<Expander Expanded="Expander_Expanded">
   <....
</Expander>

in .cs:

private void Expander_Expanded(object sender, RoutedEventArgs e)
{
    var expander = (Expander)sender;

    if(expander.DataContext == null)
    expander.DataContext = ViewModel;
}
1 голос
/ 03 апреля 2012

Хотелось бы что-нибудь подобное?

<Expander Header="Diagnostics" IsExpanded="False">
    <Expander.Style>
        <Style TargetType="Expander">
            <Setter Property="DataContext" Value="{x:Null}" />
            <Style.Triggers>                                    
                <Trigger Property="IsExpanded" Value="True">
                    <Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.Diagnostics}" />
                </Trigger>
            </Style.Triggers>
        </Style>
    </Expander.Style>

    <TextBlock Text="{Binding TestValue}" />
</Expander>

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

<Setter Property="DataContext" Value="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext}" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...