【问题标题】:How to bind the IsEnabled Property of a WPF ListBoxItem to a Property of its Source Item?如何将 WPF ListBoxItem 的 IsEnabled 属性绑定到其源项的属性?
【发布时间】:2021-09-25 03:41:31
【问题描述】:

我有一个 ObservableCollectionItemSource 的 ListBox:

public partial class HomePage : Page
{
    public ObservableCollection<DaemonFile> Files { get; private set; }
    private readonly MainWindow MainWindow;

    public HomePage(MainWindow MainWindow)
    {
        Files = new ObservableCollection<DaemonFile>();

        this.MainWindow = MainWindow;

        InitializeComponent();

        ListOfFiles.ItemsSource = Files;
    }
    ...
}

我的DaemonFile 中有以下属性:

public class DaemonFile : INotifyPropertyChanged
{
    public enum ProcessStates : int
    {
        CREATED = 0,
        CONVERTED = 1,
        UPLOADING = 2,
        FINISHED = 3
    }
    private ProcessStates ProcessStateValue = ProcessStates.CREATED;
    public ProcessStates ProcessState 
    { 
        get { return this.ProcessStateValue; } 
        set 
        {
           if (value != this.ProcessStateValue)
           {
               this.ProcessStateValue = value;
               NotifyPropertyChanged();
           }
        } 
     }
    ...
    private void NotifyPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
        {
            mainWindow.WriteLine("Property " + propertyName + " Changed!");
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        } else
        {
            mainWindow.WriteLine("Cant fire event!");
        }
    }
}

文件转换完成后,ProcessState 会异步更新。
我想我需要绑定此属性并将其放入IsEnabled 的设置器中。

        <Style x:Key="Item" TargetType="{x:Type ListBoxItem}">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ListBoxItem}">
                        <Grid Background="{TemplateBinding Background}">
                            <ContentPresenter 
                                    ContentTemplate="{TemplateBinding ContentTemplate}"
                                    Content="{TemplateBinding Content}"
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    Margin="{TemplateBinding Padding}">
                            </ContentPresenter>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <DataTrigger Binding="{Binding ProcessState}" Value="0">
                    <Setter Property="IsEnabled" Value="False"/>
                </DataTrigger> 
            </Style.Triggers>
        </Style>   

每当DaemonFile 将其ProcessState 更改为1 或更高时,我如何才能实现相应的ListBoxItem 切换为启用?

  • 我不希望用户能够在文件完成转换之前上传文件

我还可以将isEnabled 属性添加到我的DaemonFile 以简化一些事情。但这并不能解决我的绑定问题。

【问题讨论】:

    标签: c# wpf data-binding wpf-controls listboxitem


    【解决方案1】:

    您不需要那个 ControlTemplate。

    一个简单的 DataTrigger 应该可以工作:

    <Style x:Key="ItemStyle" TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding ProcessState}" Value="0">
                <Setter Property="IsEnabled" Value="False"/>
            </DataTrigger>
        </Style.Trigers>
    </Style>
    

    以防万一:

    <ListBox x:Name="ListOfFiles"
             ItemContainerStyle="{StaticResource ItemStyle}" ...>
    

    【讨论】:

    • 如果我这样做,它会被禁用但未启用。所以我根本无法与之互动。我还尝试做另一个触发器来启用它,但这似乎不起作用。顺便说一句,谢谢您的快速回答。
    • 如果您没有在其他任何地方设置 IsEnabled,它将被启用。当然,不要使用您问题中的 ControlTemplate。
    • 我是否需要在更新进程状态时触发属性更改事件?
    • 好的。我已经在 DaemonFile 类中实现了 INotifyPropertyChanged。设置进程状态时我调用 PropertyChanged.Invoke(this, new PropertyChangedEventArgs(Name));
    • 它正在更新状态,但 ui 对更改没有反应。当我将 CREATED 状态的值更改为 0 以外的值时,它会被启用。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多