简体   繁体   中英

How to bind the IsEnabled Property of a WPF ListBoxItem to a Property of its Source Item?

I have a ListBox with an ObservableCollection as ItemSource :

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;
    }
    ...
}

I have the following properties in my 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!");
        }
    }
}

The ProcessState gets updated asynchronously after the conversion of the file has finished.
I figured I need to bind this property and put it into a setter for 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>   

How can I achieve that whenever a DaemonFile changes its ProcessState to 1 or higher the corresponding ListBoxItem switches to enabled?

  • I don't want a user to be able to upload a file before it has finished converting

I could also add an isEnabled property to my DaemonFile to simplify things a little. That doesn't solve my binding problem though.

You do not need that ControlTemplate.

A simple DataTrigger should work:

<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>

Just in case:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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