0

I have a button that displays the value from a class that I created. Everything works fine, except for the fact that the button content does not refresh once the value of the binding is changed in the code. If I exit the screen and come back, the value is correct. Staying on the same screen does not refresh the button content.

The button code is shown below.

    <Grid x:Name="Task1Grid" Grid.Row="0" Grid.Column="0" Margin="5,0,5,0">
                    <Grid.RowDefinitions>
                        <RowDefinition Height=".2*"/>
                        <RowDefinition Height=".6*"/>
                        <RowDefinition Height=".2*"/>
                    </Grid.RowDefinitions>
                    <Button Grid.Row="1" Style="{StaticResource RoundedButtonStyle}" Tag="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="StoplightButton_Click" FontFamily="Global User Interface">
                        <Button.Content>
                            <Image Stretch="Uniform" Source="{Binding SelectedRepairOrder.TaskStatusGrid[0], Converter={StaticResource TaskStatusToStopLight}, Mode=OneWay}"/>
                        </Button.Content>
                        <Button.Background>
                            <ImageBrush Stretch="Uniform" ImageSource="{Binding SelectedRepairOrder.TaskStatusGrid[0], Converter={StaticResource TaskStatusToStopLight}, Mode=OneWay}"/>
                        </Button.Background>
                    </Button>
                    <Button x:Name="Task0Time"  Tag="0" Style="{StaticResource RoundedButtonStyle}" Visibility="{Binding SelectedRepairOrder.TaskStatusGrid[0].NewTaskstatus, Converter=

{StaticResource TaskStatusToVisibility}}" IsEnabled="{Binding ShowForecastFeatures}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Content="{Binding SelectedRepairOrder.TaskStatusGrid[0].TmTimecmpltask, Converter={StaticResource TaskCompleteTimeToTime}}" Grid.Row="2" Flyout="{StaticResource Task1Flyout}"/>
                    <TextBlock Grid.Row="0" Text="{Binding ClientInfo.TasksInfo[0].TaskDescription}" TextAlignment="Center" VerticalAlignment="Bottom" FontSize="28"/>
                </Grid>

The flyout code is shown below.

    <Border x:Name="StopLightBorder" Background="CornflowerBlue" Grid.Row="1" BorderBrush="White" BorderThickness="2">
        <Grid x:Name="StopLightGrid" Margin="5" >
            <Grid.Resources>
                <converter:TaskStatusToStopLight x:Key="TaskStatusToStopLight"/>
                <converter:TaskCompleteTimeToTime x:Key="TaskCompleteTimeToTime"/>
                <converter:TaskStatusToVisibility x:Key="TaskStatusToVisibility"/>
                <Flyout x:Key="Task1Flyout" >
                    <ListBox ItemsSource="{Binding ForecastTimes}" Tag="0" SelectionChanged="ForecastTimeChanged"/>
                </Flyout>

The code which changes the value for the binding is shown below.

    private void ForecastTimeChanged(object sender, SelectionChangedEventArgs e)
    {
        var timeListBox = (ListBox)sender;
        var completeTime = Convert.ToDateTime(e.AddedItems[0].ToString());
        var taskNum = Convert.ToInt16(((FrameworkElement)sender).Tag);
        var result = checkPreviousTaskTimes(completeTime, taskNum);
        switch (result)
        {
            case ForecastResult.ValidTime:
                globalContext.SelectedRepairOrder.TaskStatusGrid[taskNum].TmTimecmpltask = completeTime.ToString();
                globalContext.SelectedRepairOrder.TaskStatusGrid[taskNum].DtDateoverride = completeTime.ToString();
                globalContext.SelectedRepairOrder.TaskStatusGrid[taskNum].TmTimeoverride = completeTime.ToString();
                globalContext.SelectedRepairOrder.TaskStatusGrid[taskNum].SendOverrideForecastTime = true;
                globalContext.SelectedRepairOrder.WasChanged = true;
                globalContext.SelectedRepairOrder.RecordGrid = "1";
                ((Popup)((FlyoutPresenter)((FrameworkElement)sender).Parent).Parent).IsOpen = false;
                break;
            default:
                showForecastError(result, completeTime, taskNum);
                break;
        }     
    }

The Visibility and IsEnabled both work just fine. Not sure what else I can do at this point. It seems that changing the bound data does not have an effect until you leave the screen. I chased this issue all the way through and saw the changes to the data as well as everything else I expected. The flyout causes the forecasttimechanged method to activate. When we go to save this data to the database, the data is correct. The flyout shows the selected time when viewing it on the screen, which is what I want. I see that highlighted in the flyout.

If there is a better control to use than the button, I am all ears at this point. Here is the tricky part. This forecast time can be set in the application as well as the app you are seeing code from. The app has time in 15 minute increments, but the other program that can update this control can put in any time it wishes.

I know there is some control or parameter that needs to be set in order to make this happen properly, but for the life of me, I cannot find it. I have tried everything for the past 3 days now and nothing works.

Help me please.

user4261201
  • 2,324
  • 19
  • 26
andy
  • 11
  • 3

1 Answers1

0

I know there is some control or parameter that needs to be set in order to make this happen properly, but for the life of me, I cannot find it. I have tried everything for the past 3 days now and nothing works.

From your code, I guess the problem is that you have not implemented INotifyPropertyChanged for binding property. And your logic is complex, you could realize your feature with the easy way like the follow example.

<Button  Content="{Binding SelectItem,Mode=OneWay}">
    <Button.Flyout>
        <Flyout Placement="Top">
            <ListBox ItemsSource="{Binding Items}" SelectedItem="{Binding SelectItem,Mode=TwoWay}">
            </ListBox>
        </Flyout>
    </Button.Flyout>
</Button>

Bind the button content with SelectItem, And then the button content will be modified automatically if the ListBox SelectedItem changed.

public class MainPageViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

    public List<string> Items { get; set; } = new List<string>();

    private string selectItem = "Nico";
    public string SelectItem { get { return selectItem; } set { selectItem = value; OnPropertyChanged(); } }

    public MainPageViewModel()
    {
        Items.Add("Nico");
        Items.Add("Song");
        Items.Add("Xiao");
    }
Nico Zhu
  • 32,367
  • 2
  • 15
  • 36